@orgajs/orgx 1.0.7 → 2.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 (113) hide show
  1. package/LICENSE.org +22 -0
  2. package/dist/index.d.ts +11 -5
  3. package/dist/lib/compile.d.ts +45 -0
  4. package/dist/lib/condition.browser.d.ts +1 -0
  5. package/dist/lib/condition.d.ts +1 -0
  6. package/dist/lib/core.d.ts +57 -0
  7. package/dist/lib/evaluate.d.ts +27 -0
  8. package/dist/lib/plugin/recma-document.d.ts +63 -0
  9. package/dist/lib/plugin/recma-jsx-build.d.ts +14 -0
  10. package/dist/lib/plugin/recma-jsx-rewrite.d.ts +50 -0
  11. package/dist/lib/plugin/recma-stringify.d.ts +13 -0
  12. package/dist/lib/plugin/rehype-recma.d.ts +49 -0
  13. package/dist/lib/run.d.ts +26 -0
  14. package/dist/lib/util/estree-util-create.d.ts +13 -0
  15. package/dist/lib/util/estree-util-declaration-to-expression.d.ts +19 -0
  16. package/dist/lib/util/estree-util-is-declaration.d.ts +15 -0
  17. package/dist/lib/util/estree-util-specifiers-to-declarations.d.ts +14 -0
  18. package/dist/lib/util/estree-util-to-binary-addition.d.ts +8 -0
  19. package/dist/lib/util/estree-util-to-id-or-member-expression.d.ts +11 -0
  20. package/dist/lib/util/render-error.d.ts +2 -0
  21. package/dist/lib/util/resolve-evaluate-options.d.ts +66 -0
  22. package/dist/lib/util/resolve-file-and-options.d.ts +16 -0
  23. package/index.js +14 -0
  24. package/lib/compile.js +54 -0
  25. package/lib/condition.browser.js +1 -0
  26. package/lib/condition.js +3 -0
  27. package/lib/core.js +100 -0
  28. package/lib/evaluate.js +41 -0
  29. package/lib/plugin/recma-document.js +607 -0
  30. package/lib/plugin/recma-jsx-build.js +53 -0
  31. package/lib/plugin/recma-jsx-rewrite.js +616 -0
  32. package/lib/plugin/recma-stringify.js +42 -0
  33. package/lib/plugin/rehype-recma.js +218 -0
  34. package/lib/run.js +31 -0
  35. package/lib/types.d.ts +46 -0
  36. package/lib/util/estree-util-create.js +27 -0
  37. package/lib/util/estree-util-declaration-to-expression.js +32 -0
  38. package/lib/util/estree-util-is-declaration.js +20 -0
  39. package/lib/util/estree-util-specifiers-to-declarations.js +90 -0
  40. package/lib/util/estree-util-to-binary-addition.js +23 -0
  41. package/lib/util/estree-util-to-id-or-member-expression.js +108 -0
  42. package/lib/util/render-error.js +91 -0
  43. package/lib/util/resolve-evaluate-options.js +64 -0
  44. package/lib/util/resolve-file-and-options.js +40 -0
  45. package/package.json +36 -29
  46. package/CHANGELOG.md +0 -71
  47. package/dist/compile.d.ts +0 -6
  48. package/dist/compile.d.ts.map +0 -1
  49. package/dist/compile.js +0 -12
  50. package/dist/compile.js.map +0 -1
  51. package/dist/estree/create.d.ts +0 -2
  52. package/dist/estree/create.d.ts.map +0 -1
  53. package/dist/estree/create.js +0 -14
  54. package/dist/estree/create.js.map +0 -1
  55. package/dist/estree/declaration-to-expression.d.ts +0 -3
  56. package/dist/estree/declaration-to-expression.d.ts.map +0 -1
  57. package/dist/estree/declaration-to-expression.js +0 -12
  58. package/dist/estree/declaration-to-expression.js.map +0 -1
  59. package/dist/estree/error.d.ts +0 -61
  60. package/dist/estree/error.d.ts.map +0 -1
  61. package/dist/estree/error.js +0 -87
  62. package/dist/estree/error.js.map +0 -1
  63. package/dist/estree/is-declaration.d.ts +0 -3
  64. package/dist/estree/is-declaration.d.ts.map +0 -1
  65. package/dist/estree/is-declaration.js +0 -9
  66. package/dist/estree/is-declaration.js.map +0 -1
  67. package/dist/estree/position-from-estree.d.ts +0 -13
  68. package/dist/estree/position-from-estree.d.ts.map +0 -1
  69. package/dist/estree/position-from-estree.js +0 -34
  70. package/dist/estree/position-from-estree.js.map +0 -1
  71. package/dist/estree/specifiers-to-object-pattern.d.ts +0 -5
  72. package/dist/estree/specifiers-to-object-pattern.d.ts.map +0 -1
  73. package/dist/estree/specifiers-to-object-pattern.js +0 -33
  74. package/dist/estree/specifiers-to-object-pattern.js.map +0 -1
  75. package/dist/evaluate.d.ts +0 -22
  76. package/dist/evaluate.d.ts.map +0 -1
  77. package/dist/evaluate.js +0 -27
  78. package/dist/evaluate.js.map +0 -1
  79. package/dist/index.d.ts.map +0 -1
  80. package/dist/index.js +0 -11
  81. package/dist/index.js.map +0 -1
  82. package/dist/plugin/estree-jsx-build.d.ts +0 -6
  83. package/dist/plugin/estree-jsx-build.d.ts.map +0 -1
  84. package/dist/plugin/estree-jsx-build.js +0 -38
  85. package/dist/plugin/estree-jsx-build.js.map +0 -1
  86. package/dist/plugin/estree-jsx-rewrite.d.ts +0 -6
  87. package/dist/plugin/estree-jsx-rewrite.d.ts.map +0 -1
  88. package/dist/plugin/estree-jsx-rewrite.js +0 -214
  89. package/dist/plugin/estree-jsx-rewrite.js.map +0 -1
  90. package/dist/plugin/estree-stringify.d.ts +0 -2
  91. package/dist/plugin/estree-stringify.d.ts.map +0 -1
  92. package/dist/plugin/estree-stringify.js +0 -127
  93. package/dist/plugin/estree-stringify.js.map +0 -1
  94. package/dist/plugin/estree-wrap-in-content.d.ts +0 -18
  95. package/dist/plugin/estree-wrap-in-content.d.ts.map +0 -1
  96. package/dist/plugin/estree-wrap-in-content.js +0 -375
  97. package/dist/plugin/estree-wrap-in-content.js.map +0 -1
  98. package/dist/plugin/rehype-estree.d.ts +0 -12
  99. package/dist/plugin/rehype-estree.d.ts.map +0 -1
  100. package/dist/plugin/rehype-estree.js +0 -122
  101. package/dist/plugin/rehype-estree.js.map +0 -1
  102. package/dist/plugin/rehype-set-layout.d.ts +0 -6
  103. package/dist/plugin/rehype-set-layout.d.ts.map +0 -1
  104. package/dist/plugin/rehype-set-layout.js +0 -30
  105. package/dist/plugin/rehype-set-layout.js.map +0 -1
  106. package/dist/processor.d.ts +0 -14
  107. package/dist/processor.d.ts.map +0 -1
  108. package/dist/processor.js +0 -52
  109. package/dist/processor.js.map +0 -1
  110. package/dist/utils/remove-quotes.d.ts +0 -3
  111. package/dist/utils/remove-quotes.d.ts.map +0 -1
  112. package/dist/utils/remove-quotes.js +0 -6
  113. package/dist/utils/remove-quotes.js.map +0 -1
@@ -0,0 +1,607 @@
1
+ /**
2
+ * @typedef {import('estree-jsx').Directive} Directive
3
+ * @typedef {import('estree-jsx').ExportAllDeclaration} ExportAllDeclaration
4
+ * @typedef {import('estree-jsx').ExportDefaultDeclaration} ExportDefaultDeclaration
5
+ * @typedef {import('estree-jsx').ExportNamedDeclaration} ExportNamedDeclaration
6
+ * @typedef {import('estree-jsx').ExportSpecifier} ExportSpecifier
7
+ * @typedef {import('estree-jsx').Expression} Expression
8
+ * @typedef {import('estree-jsx').FunctionDeclaration} FunctionDeclaration
9
+ * @typedef {import('estree-jsx').ImportDeclaration} ImportDeclaration
10
+ * @typedef {import('estree-jsx').ImportDefaultSpecifier} ImportDefaultSpecifier
11
+ * @typedef {import('estree-jsx').ImportExpression} ImportExpression
12
+ * @typedef {import('estree-jsx').ImportSpecifier} ImportSpecifier
13
+ * @typedef {import('estree-jsx').Literal} Literal
14
+ * @typedef {import('estree-jsx').JSXElement} JSXElement
15
+ * @typedef {import('estree-jsx').ModuleDeclaration} ModuleDeclaration
16
+ * @typedef {import('estree-jsx').Node} Node
17
+ * @typedef {import('estree-jsx').Program} Program
18
+ * @typedef {import('estree-jsx').Property} Property
19
+ * @typedef {import('estree-jsx').SimpleLiteral} SimpleLiteral
20
+ * @typedef {import('estree-jsx').SpreadElement} SpreadElement
21
+ * @typedef {import('estree-jsx').Statement} Statement
22
+ * @typedef {import('estree-jsx').VariableDeclarator} VariableDeclarator
23
+ */
24
+
25
+ /**
26
+ * @typedef RecmaDocumentOptions
27
+ * Configuration for internal plugin `recma-document`.
28
+ * @property {'function-body' | 'program' | null | undefined} [outputFormat='program']
29
+ * Whether to use either `import` and `export` statements to get the runtime
30
+ * (and optionally provider) and export the content, or get values from
31
+ * `arguments` and return things.
32
+ * @property {boolean | null | undefined} [useDynamicImport=false]
33
+ * Whether to keep `import` (and `export … from`) statements or compile them
34
+ * to dynamic `import()` instead.
35
+ * @property {string | null | undefined} [baseUrl]
36
+ * Resolve `import`s (and `export … from`, and `import.meta.url`) relative to
37
+ * this URL.
38
+ * @property {string | null | undefined} [pragma='React.createElement']
39
+ * Pragma for JSX (used in classic runtime).
40
+ * @property {string | null | undefined} [pragmaFrag='React.Fragment']
41
+ * Pragma for JSX fragments (used in classic runtime).
42
+ * @property {string | null | undefined} [pragmaImportSource='react']
43
+ * Where to import the identifier of `pragma` from (used in classic runtime).
44
+ * @property {string | null | undefined} [jsxImportSource='react']
45
+ * Place to import automatic JSX runtimes from (used in automatic runtime).
46
+ * @property {'automatic' | 'classic' | null | undefined} [jsxRuntime='automatic']
47
+ * JSX runtime to use.
48
+ */
49
+
50
+ import { analyze } from 'periscopic'
51
+ import { stringifyPosition } from 'unist-util-stringify-position'
52
+ import { positionFromEstree } from 'unist-util-position-from-estree'
53
+ import { walk } from 'estree-walker'
54
+ import { create } from '../util/estree-util-create.js'
55
+ import { specifiersToDeclarations } from '../util/estree-util-specifiers-to-declarations.js'
56
+ import { declarationToExpression } from '../util/estree-util-declaration-to-expression.js'
57
+ import { isDeclaration } from '../util/estree-util-is-declaration.js'
58
+
59
+ /**
60
+ * A plugin to wrap the estree in `OrgContent`.
61
+ *
62
+ * @type {import('unified').Plugin<[RecmaDocumentOptions | null | undefined] | [], Program>}
63
+ */
64
+ export function recmaDocument(options) {
65
+ // Always given inside `@mdx-js/mdx`
66
+ /* c8 ignore next */
67
+ const options_ = options || {}
68
+ const baseUrl = options_.baseUrl || undefined
69
+ const useDynamicImport = options_.useDynamicImport || undefined
70
+ const outputFormat = options_.outputFormat || 'program'
71
+ const pragma =
72
+ options_.pragma === undefined ? 'React.createElement' : options_.pragma
73
+ const pragmaFrag =
74
+ options_.pragmaFrag === undefined ? 'React.Fragment' : options_.pragmaFrag
75
+ const pragmaImportSource = options_.pragmaImportSource || 'react'
76
+ const jsxImportSource = options_.jsxImportSource || 'react'
77
+ const jsxRuntime = options_.jsxRuntime || 'automatic'
78
+
79
+ return (tree, file) => {
80
+ /** @type {Array<[string, string] | string>} */
81
+ const exportedIdentifiers = []
82
+ /** @type {Array<Directive | ModuleDeclaration | Statement>} */
83
+ const replacement = []
84
+ /** @type {Array<string>} */
85
+ const pragmas = []
86
+ let exportAllCount = 0
87
+ /** @type {ExportDefaultDeclaration | ExportSpecifier | undefined} */
88
+ let layout
89
+ /** @type {boolean | undefined} */
90
+ let content
91
+ /** @type {Node} */
92
+ let child
93
+
94
+ // Patch missing comments, which types say could occur.
95
+ /* c8 ignore next */
96
+ if (!tree.comments) tree.comments = []
97
+
98
+ if (jsxRuntime) {
99
+ pragmas.push('@jsxRuntime ' + jsxRuntime)
100
+ }
101
+
102
+ if (jsxRuntime === 'automatic' && jsxImportSource) {
103
+ pragmas.push('@jsxImportSource ' + jsxImportSource)
104
+ }
105
+
106
+ if (jsxRuntime === 'classic' && pragma) {
107
+ pragmas.push('@jsx ' + pragma)
108
+ }
109
+
110
+ if (jsxRuntime === 'classic' && pragmaFrag) {
111
+ pragmas.push('@jsxFrag ' + pragmaFrag)
112
+ }
113
+
114
+ if (pragmas.length > 0) {
115
+ tree.comments.unshift({ type: 'Block', value: pragmas.join(' ') })
116
+ }
117
+
118
+ if (jsxRuntime === 'classic' && pragmaImportSource) {
119
+ if (!pragma) {
120
+ throw new Error(
121
+ 'Missing `pragma` in classic runtime with `pragmaImportSource`'
122
+ )
123
+ }
124
+
125
+ handleEsm({
126
+ type: 'ImportDeclaration',
127
+ specifiers: [
128
+ {
129
+ type: 'ImportDefaultSpecifier',
130
+ local: { type: 'Identifier', name: pragma.split('.')[0] },
131
+ },
132
+ ],
133
+ source: { type: 'Literal', value: pragmaImportSource },
134
+ })
135
+ }
136
+
137
+ // Find the `export default`, the JSX expression, and leave the rest
138
+ // (import/exports) as they are.
139
+ for (child of tree.body) {
140
+ // ```js
141
+ // export default props => <>{props.children}</>
142
+ // ```
143
+ //
144
+ // Treat it as an inline layout declaration.
145
+ if (child.type === 'ExportDefaultDeclaration') {
146
+ if (layout) {
147
+ file.fail(
148
+ 'Cannot specify multiple layouts (previous: ' +
149
+ stringifyPosition(positionFromEstree(layout)) +
150
+ ')',
151
+ positionFromEstree(child),
152
+ 'recma-document:duplicate-layout'
153
+ )
154
+ }
155
+
156
+ layout = child
157
+ replacement.push({
158
+ type: 'VariableDeclaration',
159
+ kind: 'const',
160
+ declarations: [
161
+ {
162
+ type: 'VariableDeclarator',
163
+ id: { type: 'Identifier', name: 'OrgLayout' },
164
+ init: isDeclaration(child.declaration)
165
+ ? declarationToExpression(child.declaration)
166
+ : child.declaration,
167
+ },
168
+ ],
169
+ })
170
+ }
171
+ // ```js
172
+ // export {a, b as c} from 'd'
173
+ // ```
174
+ else if (child.type === 'ExportNamedDeclaration' && child.source) {
175
+ const source = /** @type {SimpleLiteral} */ (child.source)
176
+
177
+ // Remove `default` or `as default`, but not `default as`, specifier.
178
+ child.specifiers = child.specifiers.filter((specifier) => {
179
+ if (specifier.exported.name === 'default') {
180
+ if (layout) {
181
+ file.fail(
182
+ 'Cannot specify multiple layouts (previous: ' +
183
+ stringifyPosition(positionFromEstree(layout)) +
184
+ ')',
185
+ positionFromEstree(child),
186
+ 'recma-document:duplicate-layout'
187
+ )
188
+ }
189
+
190
+ layout = specifier
191
+
192
+ // Make it just an import: `import OrgLayout from '…'`.
193
+ /** @type {Array<ImportDefaultSpecifier | ImportSpecifier>} */
194
+ const specifiers = []
195
+
196
+ // Default as default / something else as default.
197
+ if (specifier.local.name === 'default') {
198
+ specifiers.push({
199
+ type: 'ImportDefaultSpecifier',
200
+ local: { type: 'Identifier', name: 'OrgLayout' },
201
+ })
202
+ } else {
203
+ /** @type {ImportSpecifier} */
204
+ const importSpecifier = {
205
+ type: 'ImportSpecifier',
206
+ imported: specifier.local,
207
+ local: { type: 'Identifier', name: 'OrgLayout' },
208
+ }
209
+ create(specifier.local, importSpecifier)
210
+ specifiers.push(importSpecifier)
211
+ }
212
+
213
+ /** @type {Literal} */
214
+ const from = { type: 'Literal', value: source.value }
215
+ create(source, from)
216
+
217
+ /** @type {ImportDeclaration} */
218
+ const declaration = {
219
+ type: 'ImportDeclaration',
220
+ specifiers,
221
+ source: from,
222
+ }
223
+ create(specifier, declaration)
224
+ handleEsm(declaration)
225
+
226
+ return false
227
+ }
228
+
229
+ return true
230
+ })
231
+
232
+ // If there are other things imported, keep it.
233
+ if (child.specifiers.length > 0) {
234
+ handleExport(child)
235
+ }
236
+ }
237
+ // ```js
238
+ // export {a, b as c}
239
+ // export * from 'a'
240
+ // ```
241
+ else if (
242
+ child.type === 'ExportNamedDeclaration' ||
243
+ child.type === 'ExportAllDeclaration'
244
+ ) {
245
+ handleExport(child)
246
+ } else if (child.type === 'ImportDeclaration') {
247
+ handleEsm(child)
248
+ } else if (
249
+ child.type === 'ExpressionStatement' &&
250
+ // @ts-expect-error types are wrong: `JSXFragment` is an `Expression`.
251
+ (child.expression.type === 'JSXFragment' ||
252
+ child.expression.type === 'JSXElement')
253
+ ) {
254
+ content = true
255
+ replacement.push(...createMdxContent(child.expression, Boolean(layout)))
256
+ // The following catch-all branch is because plugins might’ve added
257
+ // other things.
258
+ // Normally, we only have import/export/jsx, but just add whatever’s
259
+ // there.
260
+ /* c8 ignore next 3 */
261
+ } else {
262
+ replacement.push(child)
263
+ }
264
+ }
265
+
266
+ // If there was no JSX content at all, add an empty function.
267
+ if (!content) {
268
+ replacement.push(...createMdxContent(undefined, Boolean(layout)))
269
+ }
270
+
271
+ exportedIdentifiers.push(['OrgContent', 'default'])
272
+
273
+ if (outputFormat === 'function-body') {
274
+ replacement.push({
275
+ type: 'ReturnStatement',
276
+ argument: {
277
+ type: 'ObjectExpression',
278
+ properties: [
279
+ ...Array.from({ length: exportAllCount }).map(
280
+ /**
281
+ * @param {undefined} _
282
+ * @param {number} index
283
+ * @returns {SpreadElement}
284
+ */
285
+ (_, index) => ({
286
+ type: 'SpreadElement',
287
+ argument: {
288
+ type: 'Identifier',
289
+ name: '_exportAll' + (index + 1),
290
+ },
291
+ })
292
+ ),
293
+ ...exportedIdentifiers.map((d) => {
294
+ /** @type {Property} */
295
+ const prop = {
296
+ type: 'Property',
297
+ kind: 'init',
298
+ method: false,
299
+ computed: false,
300
+ shorthand: typeof d === 'string',
301
+ key: {
302
+ type: 'Identifier',
303
+ name: typeof d === 'string' ? d : d[1],
304
+ },
305
+ value: {
306
+ type: 'Identifier',
307
+ name: typeof d === 'string' ? d : d[0],
308
+ },
309
+ }
310
+
311
+ return prop
312
+ }),
313
+ ],
314
+ },
315
+ })
316
+ } else {
317
+ replacement.push({
318
+ type: 'ExportDefaultDeclaration',
319
+ declaration: { type: 'Identifier', name: 'OrgContent' },
320
+ })
321
+ }
322
+
323
+ tree.body = replacement
324
+
325
+ if (baseUrl) {
326
+ walk(tree, {
327
+ enter(node) {
328
+ if (
329
+ node.type === 'MemberExpression' &&
330
+ 'object' in node &&
331
+ node.object.type === 'MetaProperty' &&
332
+ node.property.type === 'Identifier' &&
333
+ node.object.meta.name === 'import' &&
334
+ node.object.property.name === 'meta' &&
335
+ node.property.name === 'url'
336
+ ) {
337
+ /** @type {SimpleLiteral} */
338
+ const replacement = { type: 'Literal', value: baseUrl }
339
+ this.replace(replacement)
340
+ }
341
+ },
342
+ })
343
+ }
344
+
345
+ /**
346
+ * @param {ExportAllDeclaration | ExportNamedDeclaration} node
347
+ * @returns {void}
348
+ */
349
+ function handleExport(node) {
350
+ if (node.type === 'ExportNamedDeclaration') {
351
+ // ```js
352
+ // export function a() {}
353
+ // export class A {}
354
+ // export var a = 1
355
+ // ```
356
+ if (node.declaration) {
357
+ exportedIdentifiers.push(
358
+ ...analyze(node.declaration).scope.declarations.keys()
359
+ )
360
+ }
361
+
362
+ // ```js
363
+ // export {a, b as c}
364
+ // export {a, b as c} from 'd'
365
+ // ```
366
+ for (child of node.specifiers) {
367
+ exportedIdentifiers.push(child.exported.name)
368
+ }
369
+ }
370
+
371
+ handleEsm(node)
372
+ }
373
+
374
+ /**
375
+ * @param {ExportAllDeclaration | ExportNamedDeclaration | ImportDeclaration} node
376
+ * @returns {void}
377
+ */
378
+ function handleEsm(node) {
379
+ // Rewrite the source of the `import` / `export … from`.
380
+ // See: <https://html.spec.whatwg.org/multipage/webappapis.html#resolve-a-module-specifier>
381
+ if (baseUrl && node.source) {
382
+ let value = String(node.source.value)
383
+
384
+ try {
385
+ // A full valid URL.
386
+ value = String(new URL(value))
387
+ } catch {
388
+ // Relative: `/example.js`, `./example.js`, and `../example.js`.
389
+ if (/^\.{0,2}\//.test(value)) {
390
+ value = String(new URL(value, baseUrl))
391
+ }
392
+ // Otherwise, it’s a bare specifiers.
393
+ // For example `some-package`, `@some-package`, and
394
+ // `some-package/path`.
395
+ // These are supported in Node and browsers plan to support them
396
+ // with import maps (<https://github.com/WICG/import-maps>).
397
+ }
398
+
399
+ /** @type {Literal} */
400
+ const literal = { type: 'Literal', value }
401
+ create(node.source, literal)
402
+ node.source = literal
403
+ }
404
+
405
+ /** @type {ModuleDeclaration | Statement | undefined} */
406
+ let replace
407
+ /** @type {Expression} */
408
+ let init
409
+
410
+ if (outputFormat === 'function-body') {
411
+ if (
412
+ // Always have a source:
413
+ node.type === 'ImportDeclaration' ||
414
+ node.type === 'ExportAllDeclaration' ||
415
+ // Source optional:
416
+ (node.type === 'ExportNamedDeclaration' && node.source)
417
+ ) {
418
+ if (!useDynamicImport) {
419
+ file.fail(
420
+ 'Cannot use `import` or `export … from` in `evaluate` (outputting a function body) by default: please set `useDynamicImport: true` (and probably specify a `baseUrl`)',
421
+ positionFromEstree(node),
422
+ 'recma-document:invalid-esm-statement'
423
+ )
424
+ }
425
+
426
+ // Just for types.
427
+ /* c8 ignore next 3 */
428
+ if (!node.source) {
429
+ throw new Error('Expected `node.source` to be defined')
430
+ }
431
+
432
+ // ```
433
+ // import 'a'
434
+ // //=> await import('a')
435
+ // import a from 'b'
436
+ // //=> const {default: a} = await import('b')
437
+ // export {a, b as c} from 'd'
438
+ // //=> const {a, c: b} = await import('d')
439
+ // export * from 'a'
440
+ // //=> const _exportAll0 = await import('a')
441
+ // ```
442
+ /** @type {ImportExpression} */
443
+ const argument = { type: 'ImportExpression', source: node.source }
444
+ create(node, argument)
445
+ init = { type: 'AwaitExpression', argument }
446
+
447
+ if (
448
+ (node.type === 'ImportDeclaration' ||
449
+ node.type === 'ExportNamedDeclaration') &&
450
+ node.specifiers.length === 0
451
+ ) {
452
+ replace = { type: 'ExpressionStatement', expression: init }
453
+ } else {
454
+ replace = {
455
+ type: 'VariableDeclaration',
456
+ kind: 'const',
457
+ declarations:
458
+ node.type === 'ExportAllDeclaration'
459
+ ? [
460
+ {
461
+ type: 'VariableDeclarator',
462
+ id: {
463
+ type: 'Identifier',
464
+ name: '_exportAll' + ++exportAllCount,
465
+ },
466
+ init,
467
+ },
468
+ ]
469
+ : specifiersToDeclarations(node.specifiers, init),
470
+ }
471
+ }
472
+ } else if (node.declaration) {
473
+ replace = node.declaration
474
+ } else {
475
+ /** @type {Array<VariableDeclarator>} */
476
+ const declarators = node.specifiers
477
+ .filter(
478
+ (specifier) => specifier.local.name !== specifier.exported.name
479
+ )
480
+ .map((specifier) => ({
481
+ type: 'VariableDeclarator',
482
+ id: specifier.exported,
483
+ init: specifier.local,
484
+ }))
485
+
486
+ if (declarators.length > 0) {
487
+ replace = {
488
+ type: 'VariableDeclaration',
489
+ kind: 'const',
490
+ declarations: declarators,
491
+ }
492
+ }
493
+ }
494
+ } else {
495
+ replace = node
496
+ }
497
+
498
+ if (replace) {
499
+ replacement.push(replace)
500
+ }
501
+ }
502
+ }
503
+
504
+ /**
505
+ * @param {Expression | undefined} [content]
506
+ * @param {boolean | undefined} [hasInternalLayout]
507
+ * @returns {Array<FunctionDeclaration>}
508
+ */
509
+ function createMdxContent(content, hasInternalLayout) {
510
+ /** @type {JSXElement} */
511
+ const element = {
512
+ type: 'JSXElement',
513
+ openingElement: {
514
+ type: 'JSXOpeningElement',
515
+ name: { type: 'JSXIdentifier', name: 'OrgLayout' },
516
+ attributes: [
517
+ {
518
+ type: 'JSXSpreadAttribute',
519
+ argument: { type: 'Identifier', name: 'props' },
520
+ },
521
+ ],
522
+ selfClosing: false,
523
+ },
524
+ closingElement: {
525
+ type: 'JSXClosingElement',
526
+ name: { type: 'JSXIdentifier', name: 'OrgLayout' },
527
+ },
528
+ children: [
529
+ {
530
+ type: 'JSXElement',
531
+ openingElement: {
532
+ type: 'JSXOpeningElement',
533
+ name: { type: 'JSXIdentifier', name: '_createOrgContent' },
534
+ attributes: [
535
+ {
536
+ type: 'JSXSpreadAttribute',
537
+ argument: { type: 'Identifier', name: 'props' },
538
+ },
539
+ ],
540
+ selfClosing: true,
541
+ },
542
+ closingElement: null,
543
+ children: [],
544
+ },
545
+ ],
546
+ }
547
+
548
+ let result = /** @type {Expression} */ (element)
549
+
550
+ if (!hasInternalLayout) {
551
+ result = {
552
+ type: 'ConditionalExpression',
553
+ test: { type: 'Identifier', name: 'OrgLayout' },
554
+ consequent: result,
555
+ alternate: {
556
+ type: 'CallExpression',
557
+ callee: { type: 'Identifier', name: '_createOrgContent' },
558
+ arguments: [{ type: 'Identifier', name: 'props' }],
559
+ optional: false,
560
+ },
561
+ }
562
+ }
563
+
564
+ let argument = content || { type: 'Literal', value: null }
565
+
566
+ // Unwrap a fragment of a single element.
567
+ if (
568
+ argument &&
569
+ // @ts-expect-error: fine.
570
+ argument.type === 'JSXFragment' &&
571
+ // @ts-expect-error: fine.
572
+ argument.children.length === 1 &&
573
+ // @ts-expect-error: fine.
574
+ argument.children[0].type === 'JSXElement'
575
+ ) {
576
+ // @ts-expect-error: fine.
577
+ argument = argument.children[0]
578
+ }
579
+
580
+ return [
581
+ {
582
+ type: 'FunctionDeclaration',
583
+ id: { type: 'Identifier', name: '_createOrgContent' },
584
+ params: [{ type: 'Identifier', name: 'props' }],
585
+ body: {
586
+ type: 'BlockStatement',
587
+ body: [{ type: 'ReturnStatement', argument }],
588
+ },
589
+ },
590
+ {
591
+ type: 'FunctionDeclaration',
592
+ id: { type: 'Identifier', name: 'OrgContent' },
593
+ params: [
594
+ {
595
+ type: 'AssignmentPattern',
596
+ left: { type: 'Identifier', name: 'props' },
597
+ right: { type: 'ObjectExpression', properties: [] },
598
+ },
599
+ ],
600
+ body: {
601
+ type: 'BlockStatement',
602
+ body: [{ type: 'ReturnStatement', argument: result }],
603
+ },
604
+ },
605
+ ]
606
+ }
607
+ }
@@ -0,0 +1,53 @@
1
+ /**
2
+ * @typedef {import('estree-jsx').Program} Program
3
+ * @typedef {import('estree-util-build-jsx').BuildJsxOptions} BuildJsxOptions
4
+ */
5
+
6
+ /**
7
+ * @typedef ExtraOptions
8
+ * Configuration for internal plugin `recma-jsx-build`.
9
+ * @property {'function-body' | 'program' | null | undefined} [outputFormat='program']
10
+ * Whether to keep the import of the automatic runtime or get it from
11
+ * `arguments[0]` instead.
12
+ *
13
+ * @typedef {BuildJsxOptions & ExtraOptions} RecmaJsxBuildOptions
14
+ */
15
+
16
+ import { buildJsx } from 'estree-util-build-jsx'
17
+ import { specifiersToDeclarations } from '../util/estree-util-specifiers-to-declarations.js'
18
+ import { toIdOrMemberExpression } from '../util/estree-util-to-id-or-member-expression.js'
19
+
20
+ /**
21
+ * A plugin to build JSX into function calls.
22
+ * `estree-util-build-jsx` does all the work for us!
23
+ *
24
+ * @type {import('unified').Plugin<[RecmaJsxBuildOptions | null | undefined] | [], Program>}
25
+ */
26
+ export function recmaJsxBuild(options) {
27
+ // Always given inside `@orgajs/orgx`
28
+ const { development, outputFormat } = options || {}
29
+
30
+ return (tree, file) => {
31
+ buildJsx(tree, { development, filePath: file.history[0] })
32
+
33
+ // When compiling to a function body, replace the import that was just
34
+ // generated, and get `jsx`, `jsxs`, and `Fragment` from `arguments[0]`
35
+ // instead.
36
+ if (
37
+ outputFormat === 'function-body' &&
38
+ tree.body[0] &&
39
+ tree.body[0].type === 'ImportDeclaration' &&
40
+ typeof tree.body[0].source.value === 'string' &&
41
+ /\/jsx-(dev-)?runtime$/.test(tree.body[0].source.value)
42
+ ) {
43
+ tree.body[0] = {
44
+ type: 'VariableDeclaration',
45
+ kind: 'const',
46
+ declarations: specifiersToDeclarations(
47
+ tree.body[0].specifiers,
48
+ toIdOrMemberExpression(['arguments', 0])
49
+ ),
50
+ }
51
+ }
52
+ }
53
+ }