@builder.io/mitosis 0.7.6 → 0.9.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 (71) hide show
  1. package/dist/src/generators/angular/{blocks.d.ts → classic/blocks.d.ts} +3 -3
  2. package/dist/src/generators/angular/{blocks.js → classic/blocks.js} +14 -14
  3. package/dist/src/generators/angular/classic/component.d.ts +3 -0
  4. package/dist/src/generators/angular/classic/component.js +356 -0
  5. package/dist/src/generators/angular/classic/plugins/get-class-properties-plugin.d.ts +2 -0
  6. package/dist/src/generators/angular/classic/plugins/get-class-properties-plugin.js +138 -0
  7. package/dist/src/generators/angular/classic/plugins/get-code-processor-plugins.d.ts +8 -0
  8. package/dist/src/generators/angular/classic/plugins/get-code-processor-plugins.js +60 -0
  9. package/dist/src/generators/angular/component.d.ts +3 -0
  10. package/dist/src/generators/angular/component.js +27 -0
  11. package/dist/src/generators/angular/helpers/format.d.ts +1 -0
  12. package/dist/src/generators/angular/helpers/format.js +24 -0
  13. package/dist/src/generators/angular/helpers/get-inputs.d.ts +7 -0
  14. package/dist/src/generators/angular/helpers/get-inputs.js +18 -0
  15. package/dist/src/generators/angular/helpers/get-outputs.d.ts +7 -0
  16. package/dist/src/generators/angular/helpers/get-outputs.js +23 -0
  17. package/dist/src/generators/angular/helpers/get-refs.d.ts +8 -0
  18. package/dist/src/generators/angular/helpers/get-refs.js +40 -0
  19. package/dist/src/generators/angular/helpers/get-styles.d.ts +6 -0
  20. package/dist/src/generators/angular/helpers/get-styles.js +17 -0
  21. package/dist/src/generators/angular/helpers/index.d.ts +15 -0
  22. package/dist/src/generators/angular/helpers/index.js +126 -2
  23. package/dist/src/generators/angular/{parse-selector.d.ts → helpers/parse-selector.d.ts} +1 -1
  24. package/dist/src/generators/angular/{parse-selector.js → helpers/parse-selector.js} +3 -3
  25. package/dist/src/generators/angular/index.d.ts +1 -3
  26. package/dist/src/generators/angular/index.js +1 -692
  27. package/dist/src/generators/angular/signals/blocks.d.ts +10 -0
  28. package/dist/src/generators/angular/signals/blocks.js +242 -0
  29. package/dist/src/generators/angular/signals/component.d.ts +3 -0
  30. package/dist/src/generators/angular/signals/component.js +279 -0
  31. package/dist/src/generators/angular/signals/helpers/get-inputs.d.ts +7 -0
  32. package/dist/src/generators/angular/signals/helpers/get-inputs.js +15 -0
  33. package/dist/src/generators/angular/signals/helpers/index.d.ts +9 -0
  34. package/dist/src/generators/angular/signals/helpers/index.js +22 -0
  35. package/dist/src/generators/angular/signals/plugins/get-code-processor-plugins.d.ts +4 -0
  36. package/dist/src/generators/angular/signals/plugins/get-code-processor-plugins.js +194 -0
  37. package/dist/src/generators/angular/types.d.ts +23 -2
  38. package/dist/src/generators/angular/types.js +1 -0
  39. package/dist/src/generators/mitosis/generator.js +11 -27
  40. package/dist/src/generators/qwik/component-generator.js +1 -0
  41. package/dist/src/generators/solid/index.js +1 -0
  42. package/dist/src/generators/stencil/blocks.js +2 -1
  43. package/dist/src/generators/stencil/component.js +3 -2
  44. package/dist/src/generators/stencil/helpers/index.d.ts +0 -5
  45. package/dist/src/generators/stencil/helpers/index.js +2 -33
  46. package/dist/src/generators/stencil/plugins/get-code-processor-plugins.d.ts +1 -1
  47. package/dist/src/generators/stencil/plugins/get-code-processor-plugins.js +3 -2
  48. package/dist/src/generators/svelte/svelte.js +2 -0
  49. package/dist/src/generators/vue/vue.js +2 -0
  50. package/dist/src/helpers/babel-transform.js +1 -1
  51. package/dist/src/helpers/class-components.d.ts +13 -0
  52. package/dist/src/helpers/class-components.js +51 -0
  53. package/dist/src/helpers/get-state-object-string.d.ts +4 -0
  54. package/dist/src/helpers/get-state-object-string.js +22 -5
  55. package/dist/src/helpers/is-children.js +1 -1
  56. package/dist/src/helpers/map-refs.d.ts +7 -1
  57. package/dist/src/helpers/map-refs.js +21 -21
  58. package/dist/src/helpers/plugins/process-code/index.d.ts +1 -1
  59. package/dist/src/helpers/plugins/process-code/index.js +16 -2
  60. package/dist/src/helpers/plugins/process-code/types.d.ts +3 -2
  61. package/dist/src/helpers/render-imports.d.ts +5 -0
  62. package/dist/src/helpers/replace-identifiers.js +1 -4
  63. package/dist/src/helpers/traverse-nodes.d.ts +1 -1
  64. package/dist/src/parsers/builder/builder.d.ts +6 -0
  65. package/dist/src/parsers/builder/builder.js +25 -3
  66. package/dist/src/parsers/jsx/function-parser.js +15 -0
  67. package/dist/src/parsers/svelte/html/text.d.ts +18 -0
  68. package/dist/src/types/mitosis-component.d.ts +2 -0
  69. package/dist/src/types/mitosis-node.d.ts +7 -2
  70. package/dist/src/types/mitosis-node.js +8 -3
  71. package/package.json +1 -1
@@ -0,0 +1,194 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getCodeProcessorPlugins = void 0;
4
+ const babel_transform_1 = require("../../../../helpers/babel-transform");
5
+ const class_components_1 = require("../../../../helpers/class-components");
6
+ const event_handlers_1 = require("../../../../helpers/event-handlers");
7
+ const process_code_1 = require("../../../../helpers/plugins/process-code");
8
+ const mitosis_node_1 = require("../../../../types/mitosis-node");
9
+ const types_1 = require("@babel/types");
10
+ const isStateOrPropsExpression = (path) => {
11
+ return ((0, types_1.isMemberExpression)(path.node) &&
12
+ (0, types_1.isIdentifier)(path.node.object) &&
13
+ (0, types_1.isIdentifier)(path.node.property) &&
14
+ (path.node.object.name === 'props' || path.node.object.name === 'state'));
15
+ };
16
+ const handleAssignmentExpression = (path) => {
17
+ if ((0, types_1.isMemberExpression)(path.node.left) &&
18
+ (0, types_1.isIdentifier)(path.node.left.object) &&
19
+ (0, types_1.isIdentifier)(path.node.left.property) &&
20
+ path.node.left.object.name === 'state') {
21
+ const root = (0, types_1.memberExpression)(path.node.left, (0, types_1.identifier)('set'));
22
+ root.extra = { ...root.extra, updateExpression: true };
23
+ const call = (0, types_1.callExpression)(root, [path.node.right]);
24
+ path.replaceWith(call);
25
+ }
26
+ };
27
+ const handleMemberExpression = (path) => {
28
+ var _a, _b, _c, _d;
29
+ if (((_a = path.node.extra) === null || _a === void 0 ? void 0 : _a.makeCallExpressionDone) || ((_c = (_b = path.parentPath) === null || _b === void 0 ? void 0 : _b.node.extra) === null || _c === void 0 ? void 0 : _c.updateExpression)) {
30
+ // Don't add a function if we've done it already
31
+ return;
32
+ }
33
+ if ((0, types_1.isCallExpression)(path.parent) &&
34
+ (0, types_1.isMemberExpression)(path.parent.callee) &&
35
+ (0, types_1.isIdentifier)(path.parent.callee.object) &&
36
+ (path.parent.callee.object.name === 'props' || path.parent.callee.object.name === 'state') &&
37
+ !((_d = path.parent.callee.extra) === null || _d === void 0 ? void 0 : _d.updateExpression)) {
38
+ // Don't add a function if it is already
39
+ return;
40
+ }
41
+ if (isStateOrPropsExpression(path)) {
42
+ path.node.extra = { ...path.node.extra, makeCallExpressionDone: true };
43
+ path.replaceWith((0, types_1.callExpression)(path.node, []));
44
+ }
45
+ };
46
+ const handleHookAndStateOnEvents = (path, isHookDepArray) => {
47
+ if ((0, types_1.isIdentifier)(path.node.property) && (0, event_handlers_1.checkIsEvent)(path.node.property.name)) {
48
+ if ((0, types_1.isIfStatement)(path.parent)) {
49
+ // We don't do anything if the event is in an IfStatement
50
+ path.node.extra = { ...path.node.extra, updateExpression: true };
51
+ return true;
52
+ }
53
+ else if ((0, types_1.isCallExpression)(path.parent) &&
54
+ (0, types_1.isIdentifier)(path.node.object) &&
55
+ (0, types_1.isMemberExpression)(path.parent.callee)) {
56
+ // We add "emit" to events
57
+ const root = (0, types_1.memberExpression)(path.node, (0, types_1.identifier)('emit'));
58
+ root.extra = { ...root.extra, updateExpression: true };
59
+ path.replaceWith(root);
60
+ }
61
+ else if (isHookDepArray && (0, types_1.isIdentifier)(path.node.object)) {
62
+ const iden = (0, types_1.identifier)(`// "${path.node.object.name}.${path.node.property.name}" is an event skip it.`);
63
+ path.replaceWith(iden);
64
+ return true;
65
+ }
66
+ }
67
+ return false;
68
+ };
69
+ const transformHooksAndState = (code, isHookDepArray) => {
70
+ return (0, babel_transform_1.babelTransformExpression)(code, {
71
+ AssignmentExpression(path) {
72
+ handleAssignmentExpression(path);
73
+ },
74
+ UpdateExpression(path) {
75
+ /*
76
+ * If we have a function like this:
77
+ * `state._counter++;`
78
+ *
79
+ * We need to convert it and use the "update" example from https://angular.dev/guide/signals#writable-signals:
80
+ * `state._counter.update(_counter=>_counter++)`
81
+ *
82
+ */
83
+ if ((0, types_1.isMemberExpression)(path.node.argument) &&
84
+ (0, types_1.isIdentifier)(path.node.argument.object) &&
85
+ path.node.argument.object.name === 'state' &&
86
+ (0, types_1.isIdentifier)(path.node.argument.property)) {
87
+ const root = (0, types_1.memberExpression)(path.node.argument, (0, types_1.identifier)('update'));
88
+ root.extra = { ...root.extra, updateExpression: true };
89
+ const argument = path.node.argument.property;
90
+ const block = (0, types_1.blockStatement)([
91
+ (0, types_1.expressionStatement)((0, types_1.updateExpression)(path.node.operator, argument)),
92
+ (0, types_1.returnStatement)(argument),
93
+ ]);
94
+ const arrowFunction = (0, types_1.arrowFunctionExpression)([argument], block);
95
+ const call = (0, types_1.callExpression)(root, [arrowFunction]);
96
+ path.replaceWith(call);
97
+ }
98
+ },
99
+ MemberExpression(path) {
100
+ const skip = handleHookAndStateOnEvents(path, isHookDepArray);
101
+ if (skip) {
102
+ return;
103
+ }
104
+ handleMemberExpression(path);
105
+ },
106
+ });
107
+ };
108
+ const addToImportCall = (json, importName) => {
109
+ const isImportCall = json.imports.find((imp) => imp.imports[importName]);
110
+ const isExportCall = json.exports ? !!json.exports[importName] : false;
111
+ if (isImportCall || isExportCall) {
112
+ json.compileContext.angular.extra.importCalls.push(importName);
113
+ }
114
+ };
115
+ const transformBindings = (json, code) => {
116
+ return (0, babel_transform_1.babelTransformExpression)(code, {
117
+ BlockStatement() {
118
+ console.error(`
119
+ Component ${json.name} has a BlockStatement inside JSX'.
120
+ This will cause an error in Angular.
121
+ Please create and call a new function instead with this code:
122
+ ${code}`);
123
+ },
124
+ CallExpression(path) {
125
+ // If we call a function from an import we need to add it to the Component as well
126
+ if ((0, types_1.isIdentifier)(path.node.callee)) {
127
+ addToImportCall(json, path.node.callee.name);
128
+ }
129
+ },
130
+ Identifier(path) {
131
+ // If we use a constant from an import we need to add it to the Component as well
132
+ if ((0, types_1.isIdentifier)(path.node)) {
133
+ addToImportCall(json, path.node.name);
134
+ }
135
+ },
136
+ StringLiteral(path) {
137
+ var _a;
138
+ // We cannot use " for string literal in template
139
+ if ((_a = path.node.extra) === null || _a === void 0 ? void 0 : _a.raw) {
140
+ path.node.extra.raw = path.node.extra.raw.replaceAll('"', "'");
141
+ }
142
+ },
143
+ AssignmentExpression(path) {
144
+ handleAssignmentExpression(path);
145
+ },
146
+ MemberExpression(path) {
147
+ handleMemberExpression(path);
148
+ },
149
+ });
150
+ };
151
+ const getCodeProcessorPlugins = (json, options, processBindingOptions) => {
152
+ return [
153
+ ...(options.plugins || []),
154
+ (0, process_code_1.CODE_PROCESSOR_PLUGIN)((codeType) => {
155
+ switch (codeType) {
156
+ case 'bindings':
157
+ return (code, key, context) => {
158
+ var _a, _b, _c;
159
+ let replaceWith = '';
160
+ if (key === 'key') {
161
+ /**
162
+ * If we have a key attribute we need to check if it is inside a @for loop.
163
+ * We will create a new function for the key attribute.
164
+ * Therefore, we need to add "this" to state and props.
165
+ */
166
+ const isForParent = ((_c = (_b = (_a = context === null || context === void 0 ? void 0 : context.parent) === null || _a === void 0 ? void 0 : _a.parent) === null || _b === void 0 ? void 0 : _b.node) === null || _c === void 0 ? void 0 : _c.name) === mitosis_node_1.ForNodeName;
167
+ if (isForParent) {
168
+ replaceWith = 'this.';
169
+ }
170
+ }
171
+ return (0, class_components_1.processClassComponentBinding)(json, transformBindings(json, code), {
172
+ ...processBindingOptions,
173
+ replaceWith,
174
+ });
175
+ };
176
+ case 'hooks-deps-array':
177
+ case 'hooks':
178
+ case 'state':
179
+ return (code) => {
180
+ return (0, class_components_1.processClassComponentBinding)(json, transformHooksAndState(code, codeType === 'hooks-deps-array'), processBindingOptions);
181
+ };
182
+ case 'properties':
183
+ case 'hooks-deps':
184
+ case 'context-set':
185
+ case 'dynamic-jsx-elements':
186
+ case 'types':
187
+ return (code) => {
188
+ return (0, class_components_1.processClassComponentBinding)(json, code, processBindingOptions);
189
+ };
190
+ }
191
+ }),
192
+ ];
193
+ };
194
+ exports.getCodeProcessorPlugins = getCodeProcessorPlugins;
@@ -1,7 +1,8 @@
1
- import { MitosisComponent } from '../../types/mitosis-component';
2
1
  import { BaseTranspilerOptions } from '../../types/transpiler';
3
2
  export declare const BUILT_IN_COMPONENTS: Set<string>;
3
+ export type AngularApi = 'classic' | 'signals';
4
4
  export interface ToAngularOptions extends BaseTranspilerOptions {
5
+ api?: AngularApi;
5
6
  state?: 'class-properties' | 'inline-with-wrappers';
6
7
  standalone?: boolean;
7
8
  preserveImports?: boolean;
@@ -12,7 +13,6 @@ export interface ToAngularOptions extends BaseTranspilerOptions {
12
13
  experimental?: {
13
14
  injectables?: (variableName: string, variableType: string) => string;
14
15
  inject?: boolean;
15
- outputs?: (json: MitosisComponent, variableName: string) => string;
16
16
  };
17
17
  }
18
18
  export declare const DEFAULT_ANGULAR_OPTIONS: ToAngularOptions;
@@ -28,6 +28,7 @@ export type AngularMetadata = {
28
28
  */
29
29
  nativeEvents?: string[];
30
30
  /**
31
+ * @deprecated Rename component in *.lite.tsx
31
32
  * Overwrite default selector for component. Default will be kebab case (MyComponent -> my-component)
32
33
  */
33
34
  selector?: string;
@@ -40,6 +41,26 @@ export type AngularMetadata = {
40
41
  * Overwrite default sanitizeInnerHTML. Default is `false`
41
42
  */
42
43
  sanitizeInnerHTML?: boolean;
44
+ /**
45
+ * @deprecated Only for api=classic
46
+ * Add additional @Output() properties to the component.
47
+ * Can be used with `useTarget({angular: ()=> ...})` if needed.
48
+ */
49
+ outputs?: string[];
50
+ /**
51
+ * Only for api=signals
52
+ */
53
+ signals?: {
54
+ /**
55
+ * Turns every property in this array to [`model`](https://angular.dev/api/core/model).
56
+ * This is useful if you want to use ngModel(`[(prop)]`) syntax in Angular.
57
+ */
58
+ writeable?: string[];
59
+ /**
60
+ * Adds [`.required`](https://angular.dev/api/core/input#required()) to the `input()` properties.
61
+ */
62
+ required?: string[];
63
+ };
43
64
  };
44
65
  export type AngularBlockOptions = {
45
66
  childComponents?: string[];
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.DEFAULT_ANGULAR_OPTIONS = exports.BUILT_IN_COMPONENTS = void 0;
4
4
  exports.BUILT_IN_COMPONENTS = new Set(['Show', 'For', 'Fragment', 'Slot']);
5
5
  exports.DEFAULT_ANGULAR_OPTIONS = {
6
+ api: 'classic',
6
7
  state: 'inline-with-wrappers',
7
8
  preserveImports: false,
8
9
  preserveFileExtensions: false,
@@ -1,27 +1,4 @@
1
1
  "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || function (mod) {
19
- if (mod && mod.__esModule) return mod;
20
- var result = {};
21
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
- __setModuleDefault(result, mod);
23
- return result;
24
- };
25
2
  var __importDefault = (this && this.__importDefault) || function (mod) {
26
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
27
4
  };
@@ -42,8 +19,6 @@ const render_imports_1 = require("../../helpers/render-imports");
42
19
  const state_1 = require("../../helpers/state");
43
20
  const plugins_1 = require("../../modules/plugins");
44
21
  const mitosis_node_1 = require("../../types/mitosis-node");
45
- const babel = __importStar(require("@babel/core"));
46
- const plugin_syntax_typescript_1 = __importDefault(require("@babel/plugin-syntax-typescript"));
47
22
  const json5_1 = __importDefault(require("json5"));
48
23
  const standalone_1 = require("prettier/standalone");
49
24
  const react_1 = require("../react");
@@ -126,8 +101,17 @@ const blockToMitosis = (json, toMitosisOptions = {}, component, insideJsx) => {
126
101
  if (text.includes('<') || text.includes('>')) {
127
102
  // test if this can parse as jsx
128
103
  try {
129
- babel.parse(`let _ = <>${text}</>;`, {
130
- plugins: [[plugin_syntax_typescript_1.default, { isTSX: true }]],
104
+ /**
105
+ * We intentionally use the typescript parser here because texts like ">" will crash
106
+ * in the typescript parser but will not crash in the babel parser. The Prettier
107
+ * formatting that is run after JSX is generated also uses the typescript parser,
108
+ * so we want to make sure that doesn't crash.
109
+ */
110
+ (0, standalone_1.check)(`let _ = <>${text}</>;`, {
111
+ parser: 'typescript',
112
+ plugins: [
113
+ require('prettier/parser-typescript'), // To support running in browsers
114
+ ],
131
115
  });
132
116
  isInvalidJsx = false;
133
117
  }
@@ -38,6 +38,7 @@ const PLUGINS = [
38
38
  case 'context-set':
39
39
  case 'hooks':
40
40
  case 'hooks-deps':
41
+ case 'hooks-deps-array':
41
42
  case 'properties':
42
43
  case 'dynamic-jsx-elements':
43
44
  // update signal getters to have `.value`
@@ -135,6 +135,7 @@ const componentToSolid = (passedOptions) => ({ component }) => {
135
135
  case 'bindings':
136
136
  case 'hooks':
137
137
  case 'hooks-deps':
138
+ case 'hooks-deps-array':
138
139
  case 'properties':
139
140
  return (0, helpers_2.updateStateCode)({
140
141
  component: json,
@@ -4,6 +4,7 @@ exports.blockToStencil = void 0;
4
4
  const html_tags_1 = require("../../constants/html_tags");
5
5
  const helpers_1 = require("../../generators/stencil/helpers");
6
6
  const collect_class_string_1 = require("../../generators/stencil/helpers/collect-class-string");
7
+ const event_handlers_1 = require("../../helpers/event-handlers");
7
8
  const filter_empty_text_nodes_1 = require("../../helpers/filter-empty-text-nodes");
8
9
  const for_1 = require("../../helpers/nodes/for");
9
10
  const transform_to_jsx_1 = require("../../helpers/transform-to-jsx");
@@ -93,7 +94,7 @@ const blockToStencil = ({ json, options = {}, insideJsx, rootRef, childComponent
93
94
  ${code.startsWith('this.') ? code : `this.${code}`} = el}
94
95
  } `;
95
96
  }
96
- else if ((0, helpers_1.isEvent)(key)) {
97
+ else if ((0, event_handlers_1.checkIsEvent)(key)) {
97
98
  const asyncKeyword = ((_g = json.bindings[key]) === null || _g === void 0 ? void 0 : _g.async) ? 'async ' : '';
98
99
  str += ` ${key}={${asyncKeyword}(${cusArgs.join(',')}) => ${code}} `;
99
100
  }
@@ -7,6 +7,7 @@ const helpers_1 = require("../../generators/stencil/helpers");
7
7
  const get_code_processor_plugins_1 = require("../../generators/stencil/plugins/get-code-processor-plugins");
8
8
  const dash_case_1 = require("../../helpers/dash-case");
9
9
  const dedent_1 = require("../../helpers/dedent");
10
+ const event_handlers_1 = require("../../helpers/event-handlers");
10
11
  const fast_clone_1 = require("../../helpers/fast-clone");
11
12
  const get_child_components_1 = require("../../helpers/get-child-components");
12
13
  const get_props_1 = require("../../helpers/get-props");
@@ -36,14 +37,14 @@ const componentToStencil = (_options = {
36
37
  (0, map_refs_1.mapRefs)(json, (refName) => `this.${refName}`);
37
38
  let css = (0, collect_css_1.collectCss)(json);
38
39
  let props = Array.from((0, get_props_1.getProps)(json));
39
- const events = props.filter((prop) => (0, helpers_1.isEvent)(prop));
40
+ const events = props.filter((prop) => (0, event_handlers_1.checkIsEvent)(prop));
40
41
  const defaultProps = json.defaultProps;
41
42
  const childComponents = (0, get_child_components_1.getChildComponents)(json);
42
- const processBindingOptions = { events };
43
43
  props = props.filter((prop) => {
44
44
  // Stencil doesn't need children as a prop
45
45
  return prop !== 'children';
46
46
  });
47
+ const processBindingOptions = { events, props, target: 'stencil' };
47
48
  options.plugins = (0, get_code_processor_plugins_1.getCodeProcessorPlugins)(json, options, processBindingOptions);
48
49
  if (options.plugins) {
49
50
  json = (0, plugins_1.runPostJsonPlugins)({ json, plugins: options.plugins });
@@ -1,11 +1,6 @@
1
1
  import { StencilPropOption, ToStencilOptions } from '../../../generators/stencil/types';
2
2
  import { MitosisComponent, MitosisState } from '../../../types/mitosis-component';
3
3
  import { MitosisNode } from '../../../types/mitosis-node';
4
- export declare const isEvent: (key: string) => boolean;
5
- export type ProcessBindingOptions = {
6
- events: string[];
7
- };
8
- export declare const processBinding: (json: MitosisComponent, code: string, { events }: ProcessBindingOptions) => string;
9
4
  export declare const getTagName: (name: string, { prefix }: ToStencilOptions) => string;
10
5
  export declare const getPropsAsCode: ({ props, propOptions, defaultProps, json, }: {
11
6
  props: string[];
@@ -1,40 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getExportsAndLocal = exports.getDepsAsArray = exports.getImports = exports.getStencilCoreImportsAsString = exports.needsWrap = exports.getPropsAsCode = exports.getTagName = exports.processBinding = exports.isEvent = void 0;
3
+ exports.getExportsAndLocal = exports.getDepsAsArray = exports.getImports = exports.getStencilCoreImportsAsString = exports.needsWrap = exports.getPropsAsCode = exports.getTagName = void 0;
4
4
  const dash_case_1 = require("../../../helpers/dash-case");
5
5
  const event_handlers_1 = require("../../../helpers/event-handlers");
6
6
  const render_imports_1 = require("../../../helpers/render-imports");
7
- const strip_state_and_props_refs_1 = require("../../../helpers/strip-state-and-props-refs");
8
- const isEvent = (key) => (0, event_handlers_1.checkIsEvent)(key);
9
- exports.isEvent = isEvent;
10
- /**
11
- * We need to "emit" events those can be on multiple places, so we do it as post step
12
- */
13
- const appendEmits = (str, events) => {
14
- let code = str;
15
- if (events.length) {
16
- for (const event of events) {
17
- const eventWithoutOn = (0, event_handlers_1.getEventNameWithoutOn)(event);
18
- code = code
19
- .replaceAll(`props.${event}(`, `props.${eventWithoutOn}.emit(`)
20
- .replaceAll(`props.${event}`, `props.${eventWithoutOn}`);
21
- }
22
- }
23
- return code;
24
- };
25
- const processBinding = (json, code, { events }) => {
26
- let resolvedCode = (0, strip_state_and_props_refs_1.stripStateAndPropsRefs)(appendEmits(code, events), { replaceWith: 'this.' });
27
- if (json.exports) {
28
- // We need to use local exports with `this.` in stencil
29
- Object.entries(json.exports)
30
- .filter(([, value]) => value.usedInLocal)
31
- .forEach(([key]) => {
32
- resolvedCode = resolvedCode.replaceAll(key, `this.${key}`);
33
- });
34
- }
35
- return resolvedCode;
36
- };
37
- exports.processBinding = processBinding;
38
7
  const getTagName = (name, { prefix }) => {
39
8
  const dashName = (0, dash_case_1.dashCase)(name);
40
9
  if (prefix) {
@@ -61,7 +30,7 @@ const getPropsAsCode = ({ props, propOptions, defaultProps, json, }) => {
61
30
  propsTypeRef !== 'unknown' &&
62
31
  propsTypeRef !== 'never' &&
63
32
  !isInternalType;
64
- if ((0, exports.isEvent)(item)) {
33
+ if ((0, event_handlers_1.checkIsEvent)(item)) {
65
34
  // Stencil adds "on" to every `@Event` so we need to remove "on" from event props
66
35
  // https://stenciljs.com/docs/events#using-events-in-jsx
67
36
  const eventType = hasTyping
@@ -1,4 +1,4 @@
1
- import { ProcessBindingOptions } from '../../../generators/stencil/helpers';
2
1
  import { ToStencilOptions } from '../../../generators/stencil/types';
2
+ import { ProcessBindingOptions } from '../../../helpers/class-components';
3
3
  import { MitosisComponent } from '../../../types/mitosis-component';
4
4
  export declare const getCodeProcessorPlugins: (json: MitosisComponent, options: ToStencilOptions, processBindingOptions: ProcessBindingOptions) => import("../../..").MitosisPlugin[];
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getCodeProcessorPlugins = void 0;
4
- const helpers_1 = require("../../../generators/stencil/helpers");
4
+ const class_components_1 = require("../../../helpers/class-components");
5
5
  const process_code_1 = require("../../../helpers/plugins/process-code");
6
6
  const getCodeProcessorPlugins = (json, options, processBindingOptions) => {
7
7
  return [
@@ -12,11 +12,12 @@ const getCodeProcessorPlugins = (json, options, processBindingOptions) => {
12
12
  case 'properties':
13
13
  case 'hooks':
14
14
  case 'hooks-deps':
15
+ case 'hooks-deps-array':
15
16
  case 'state':
16
17
  case 'context-set':
17
18
  case 'dynamic-jsx-elements':
18
19
  case 'types':
19
- return (code) => (0, helpers_1.processBinding)(json, code, processBindingOptions);
20
+ return (code) => (0, class_components_1.processClassComponentBinding)(json, code, processBindingOptions);
20
21
  }
21
22
  }),
22
23
  ];
@@ -153,6 +153,7 @@ const componentToSvelte = (userProvidedOptions) => ({ component }) => {
153
153
  return babel_transform_1.convertTypeScriptToJS;
154
154
  case 'hooks':
155
155
  case 'hooks-deps':
156
+ case 'hooks-deps-array':
156
157
  case 'state':
157
158
  case 'context-set':
158
159
  case 'dynamic-jsx-elements':
@@ -172,6 +173,7 @@ const componentToSvelte = (userProvidedOptions) => ({ component }) => {
172
173
  case 'context-set':
173
174
  return (0, function_1.flow)((0, helpers_2.stripStateAndProps)({ json, options }));
174
175
  case 'dynamic-jsx-elements':
176
+ case 'hooks-deps-array':
175
177
  case 'types':
176
178
  return (x) => x;
177
179
  }
@@ -121,6 +121,7 @@ const componentToVue = (userOptions) => ({ component: _component, path }) => {
121
121
  return (0, replace_identifiers_1.replaceStateIdentifier)(null);
122
122
  case 'properties':
123
123
  case 'dynamic-jsx-elements':
124
+ case 'hooks-deps-array':
124
125
  case 'types':
125
126
  return (c) => c;
126
127
  }
@@ -136,6 +137,7 @@ const componentToVue = (userOptions) => ({ component: _component, path }) => {
136
137
  case 'properties':
137
138
  case 'dynamic-jsx-elements':
138
139
  case 'hooks-deps':
140
+ case 'hooks-deps-array':
139
141
  case 'types':
140
142
  return (c) => c;
141
143
  case 'state':
@@ -57,7 +57,7 @@ const handleErrorOrExpression = ({ code, useCode, result, visitor, stripTypes, }
57
57
  return result;
58
58
  }
59
59
  catch (err) {
60
- // console.error('Error parsing code:\n', { code, result, useCode });
60
+ console.error('Error parsing code:\n', { code, result, useCode });
61
61
  throw err;
62
62
  }
63
63
  };
@@ -0,0 +1,13 @@
1
+ import { Target } from '../types/config';
2
+ import { MitosisComponent } from '../types/mitosis-component';
3
+ export type ProcessBindingOptions = {
4
+ events: string[];
5
+ props: string[];
6
+ target: Target;
7
+ replaceWith?: string;
8
+ skipAppendEmit?: boolean;
9
+ };
10
+ /**
11
+ * We use this for generators like stencil and angular
12
+ */
13
+ export declare const processClassComponentBinding: (json: MitosisComponent, code: string, processBindingOptions: ProcessBindingOptions) => string;
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.processClassComponentBinding = void 0;
4
+ const strip_state_and_props_refs_1 = require("../helpers/strip-state-and-props-refs");
5
+ const event_handlers_1 = require("./event-handlers");
6
+ /**
7
+ * We need to "emit" events those can be on multiple places, so we do it as post step
8
+ */
9
+ const appendEmits = (str, { name }, { events, props, target, skipAppendEmit }) => {
10
+ let code = str;
11
+ if (events.length) {
12
+ for (const event of events) {
13
+ const eventWithoutOn = (0, event_handlers_1.getEventNameWithoutOn)(event);
14
+ if (props.includes(eventWithoutOn)) {
15
+ console.error(`
16
+ Component ${name} has an event ${event} that conflicts with prop ${eventWithoutOn} for target ${target}.
17
+ Please rename the prop or the event.
18
+ `);
19
+ }
20
+ if (!skipAppendEmit) {
21
+ code = code.replaceAll(`props.${event}(`, `props.${eventWithoutOn}.emit(`);
22
+ }
23
+ code = code.replaceAll(`props.${event}`, `props.${eventWithoutOn}`);
24
+ }
25
+ }
26
+ return code;
27
+ };
28
+ /**
29
+ * We use this for generators like stencil and angular
30
+ */
31
+ const processClassComponentBinding = (json, code, processBindingOptions) => {
32
+ const { replaceWith = 'this.' } = processBindingOptions;
33
+ let resolvedCode = (0, strip_state_and_props_refs_1.stripStateAndPropsRefs)(appendEmits(code, json, processBindingOptions), {
34
+ replaceWith,
35
+ });
36
+ if (json.exports) {
37
+ // We need to use local exports with `this.` in stencil and angular
38
+ Object.entries(json.exports)
39
+ .filter(([, value]) => value.usedInLocal)
40
+ .forEach(([key]) => {
41
+ resolvedCode = resolvedCode.replaceAll(key, `${replaceWith}${key}`);
42
+ });
43
+ }
44
+ if (json.context.get) {
45
+ for (const key of Object.keys(json.context.get)) {
46
+ resolvedCode = resolvedCode.replaceAll(key, `${replaceWith}${key}`);
47
+ }
48
+ }
49
+ return resolvedCode;
50
+ };
51
+ exports.processClassComponentBinding = processClassComponentBinding;
@@ -6,6 +6,10 @@ interface GetStateObjectStringOptions {
6
6
  functions?: boolean;
7
7
  getters?: boolean;
8
8
  valueMapper?: ValueMapper;
9
+ /**
10
+ * If you want the plain value mapper as output
11
+ */
12
+ onlyValueMapper?: boolean;
9
13
  format?: 'object' | 'class' | 'variables';
10
14
  keyPrefix?: string;
11
15
  withType?: boolean;
@@ -5,12 +5,13 @@ const DEFAULT_OPTIONS = {
5
5
  format: 'object',
6
6
  keyPrefix: '',
7
7
  valueMapper: (val) => val,
8
+ onlyValueMapper: false,
8
9
  data: true,
9
10
  functions: true,
10
11
  getters: true,
11
12
  withType: false,
12
13
  };
13
- const convertStateMemberToString = ({ data, format, functions, getters, keyPrefix, valueMapper, withType }) => ([key, state]) => {
14
+ const convertStateMemberToString = ({ data, format, functions, getters, keyPrefix, valueMapper, withType, onlyValueMapper, }) => ([key, state]) => {
14
15
  const keyValueDelimiter = format === 'object' ? ':' : '=';
15
16
  if (!state) {
16
17
  return undefined;
@@ -22,25 +23,41 @@ const convertStateMemberToString = ({ data, format, functions, getters, keyPrefi
22
23
  if (!functions) {
23
24
  return undefined;
24
25
  }
25
- return `${keyPrefix} ${key} ${keyValueDelimiter} ${valueMapper(code, 'function', typeParameter, key)}`;
26
+ const mapper = valueMapper(code, 'function', typeParameter, key);
27
+ if (onlyValueMapper) {
28
+ return mapper;
29
+ }
30
+ return `${keyPrefix} ${key} ${keyValueDelimiter} ${mapper}`;
26
31
  }
27
32
  case 'method': {
28
33
  if (!functions) {
29
34
  return undefined;
30
35
  }
31
- return `${keyPrefix} ${valueMapper(code, 'function', typeParameter, key)}`;
36
+ const mapper = valueMapper(code, 'function', typeParameter, key);
37
+ if (onlyValueMapper) {
38
+ return mapper;
39
+ }
40
+ return `${keyPrefix} ${mapper}`;
32
41
  }
33
42
  case 'getter': {
34
43
  if (!getters) {
35
44
  return undefined;
36
45
  }
37
- return `${keyPrefix} ${valueMapper(code, 'getter', typeParameter, key)}`;
46
+ const mapper = valueMapper(code, 'getter', typeParameter, key);
47
+ if (onlyValueMapper) {
48
+ return mapper;
49
+ }
50
+ return `${keyPrefix} ${mapper}`;
38
51
  }
39
52
  case 'property': {
40
53
  if (!data) {
41
54
  return undefined;
42
55
  }
43
- return `${keyPrefix} ${key}${type}${keyValueDelimiter} ${valueMapper(code, 'data', typeParameter, key)}`;
56
+ const mapper = valueMapper(code, 'data', typeParameter, key);
57
+ if (onlyValueMapper) {
58
+ return mapper;
59
+ }
60
+ return `${keyPrefix} ${key}${type}${keyValueDelimiter} ${mapper}`;
44
61
  }
45
62
  default:
46
63
  break;