vite-plugin-ferry 0.1.2 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +246 -2
- package/dist/generators/enums.d.ts +3 -1
- package/dist/generators/enums.d.ts.map +1 -1
- package/dist/generators/enums.js +45 -52
- package/dist/generators/resources.d.ts +4 -6
- package/dist/generators/resources.d.ts.map +1 -1
- package/dist/generators/resources.js +35 -197
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -8
- package/dist/utils/php-parser.d.ts +29 -12
- package/dist/utils/php-parser.d.ts.map +1 -1
- package/dist/utils/php-parser.js +524 -73
- package/dist/utils/ts-generator.d.ts +67 -0
- package/dist/utils/ts-generator.d.ts.map +1 -0
- package/dist/utils/ts-generator.js +179 -0
- package/package.json +11 -3
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import ts from 'typescript';
|
|
2
|
+
/**
|
|
3
|
+
* Print a TypeScript node to a string.
|
|
4
|
+
*/
|
|
5
|
+
export declare function printNode(node: ts.Node): string;
|
|
6
|
+
/**
|
|
7
|
+
* Print multiple TypeScript nodes to a string with blank lines between them.
|
|
8
|
+
*/
|
|
9
|
+
export declare function printNodes(nodes: ts.Node[]): string;
|
|
10
|
+
/**
|
|
11
|
+
* Create a string literal type node.
|
|
12
|
+
*/
|
|
13
|
+
export declare function createStringLiteral(value: string): ts.StringLiteral;
|
|
14
|
+
/**
|
|
15
|
+
* Create a numeric literal node.
|
|
16
|
+
*/
|
|
17
|
+
export declare function createNumericLiteral(value: number): ts.NumericLiteral;
|
|
18
|
+
/**
|
|
19
|
+
* Create an enum declaration.
|
|
20
|
+
*/
|
|
21
|
+
export declare function createEnum(name: string, members: Array<{
|
|
22
|
+
key: string;
|
|
23
|
+
value: string | number;
|
|
24
|
+
}>): ts.EnumDeclaration;
|
|
25
|
+
/**
|
|
26
|
+
* Create an object literal expression.
|
|
27
|
+
*/
|
|
28
|
+
export declare function createObjectLiteral(properties: Array<{
|
|
29
|
+
key: string;
|
|
30
|
+
value: ts.Expression;
|
|
31
|
+
}>, multiLine?: boolean): ts.ObjectLiteralExpression;
|
|
32
|
+
/**
|
|
33
|
+
* Create a const declaration with an object literal.
|
|
34
|
+
*/
|
|
35
|
+
export declare function createConstObject(name: string, properties: Array<{
|
|
36
|
+
key: string;
|
|
37
|
+
value: ts.Expression;
|
|
38
|
+
}>, multiLine?: boolean): ts.VariableStatement;
|
|
39
|
+
/**
|
|
40
|
+
* Create a declare const statement with a typed object.
|
|
41
|
+
*/
|
|
42
|
+
export declare function createDeclareConstWithType(name: string, type: ts.TypeNode): ts.VariableStatement;
|
|
43
|
+
/**
|
|
44
|
+
* Create a type alias declaration.
|
|
45
|
+
*/
|
|
46
|
+
export declare function createTypeAlias(name: string, type: ts.TypeNode): ts.TypeAliasDeclaration;
|
|
47
|
+
/**
|
|
48
|
+
* Create a type literal with property signatures.
|
|
49
|
+
*/
|
|
50
|
+
export declare function createTypeLiteral(properties: Array<{
|
|
51
|
+
name: string;
|
|
52
|
+
type: ts.TypeNode;
|
|
53
|
+
optional?: boolean;
|
|
54
|
+
}>): ts.TypeLiteralNode;
|
|
55
|
+
/**
|
|
56
|
+
* Create an import type declaration.
|
|
57
|
+
*/
|
|
58
|
+
export declare function createImportType(names: string[], from: string): ts.ImportDeclaration;
|
|
59
|
+
/**
|
|
60
|
+
* Parse a type string into a TypeNode.
|
|
61
|
+
*/
|
|
62
|
+
export declare function parseTypeString(typeStr: string): ts.TypeNode;
|
|
63
|
+
/**
|
|
64
|
+
* Create an export default statement.
|
|
65
|
+
*/
|
|
66
|
+
export declare function createExportDefault(expression: ts.Expression): ts.ExportAssignment;
|
|
67
|
+
//# sourceMappingURL=ts-generator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ts-generator.d.ts","sourceRoot":"","sources":["../../src/utils/ts-generator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,YAAY,CAAC;AAI5B;;GAEG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,GAAG,MAAM,CAG/C;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,EAAE,GAAG,MAAM,CAEnD;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,EAAE,CAAC,aAAa,CAEnE;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,EAAE,CAAC,cAAc,CAErE;AAED;;GAEG;AACH,wBAAgB,UAAU,CACxB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,KAAK,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,CAAC,GACtD,EAAE,CAAC,eAAe,CAWpB;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,UAAU,EAAE,KAAK,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,EAAE,CAAC,UAAU,CAAA;CAAE,CAAC,EACxD,SAAS,UAAO,GACf,EAAE,CAAC,uBAAuB,CAK5B;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,KAAK,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,EAAE,CAAC,UAAU,CAAA;CAAE,CAAC,EACxD,SAAS,UAAO,GACf,EAAE,CAAC,iBAAiB,CAUtB;AAED;;GAEG;AACH,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,CAAC,QAAQ,GAAG,EAAE,CAAC,iBAAiB,CAQhG;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,CAAC,QAAQ,GAAG,EAAE,CAAC,oBAAoB,CAOxF;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,UAAU,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,EAAE,CAAC,QAAQ,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC,GACzE,EAAE,CAAC,eAAe,CAUpB;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,GAAG,EAAE,CAAC,iBAAiB,CAcpF;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,EAAE,CAAC,QAAQ,CAiD5D;AAkDD;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,EAAE,CAAC,UAAU,GAAG,EAAE,CAAC,gBAAgB,CAElF"}
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
import ts from 'typescript';
|
|
2
|
+
const printer = ts.createPrinter({ newLine: ts.NewLineKind.LineFeed });
|
|
3
|
+
/**
|
|
4
|
+
* Print a TypeScript node to a string.
|
|
5
|
+
*/
|
|
6
|
+
export function printNode(node) {
|
|
7
|
+
const sourceFile = ts.createSourceFile('output.ts', '', ts.ScriptTarget.Latest, false, ts.ScriptKind.TS);
|
|
8
|
+
return printer.printNode(ts.EmitHint.Unspecified, node, sourceFile);
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Print multiple TypeScript nodes to a string with blank lines between them.
|
|
12
|
+
*/
|
|
13
|
+
export function printNodes(nodes) {
|
|
14
|
+
return nodes.map(printNode).join('\n\n');
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Create a string literal type node.
|
|
18
|
+
*/
|
|
19
|
+
export function createStringLiteral(value) {
|
|
20
|
+
return ts.factory.createStringLiteral(value);
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Create a numeric literal node.
|
|
24
|
+
*/
|
|
25
|
+
export function createNumericLiteral(value) {
|
|
26
|
+
return ts.factory.createNumericLiteral(value);
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Create an enum declaration.
|
|
30
|
+
*/
|
|
31
|
+
export function createEnum(name, members) {
|
|
32
|
+
const enumMembers = members.map((m) => {
|
|
33
|
+
const initializer = typeof m.value === 'number' ? createNumericLiteral(m.value) : createStringLiteral(m.value);
|
|
34
|
+
return ts.factory.createEnumMember(ts.factory.createIdentifier(m.key), initializer);
|
|
35
|
+
});
|
|
36
|
+
return ts.factory.createEnumDeclaration([ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)], ts.factory.createIdentifier(name), enumMembers);
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Create an object literal expression.
|
|
40
|
+
*/
|
|
41
|
+
export function createObjectLiteral(properties, multiLine = true) {
|
|
42
|
+
const objectProperties = properties.map((p) => ts.factory.createPropertyAssignment(ts.factory.createIdentifier(p.key), p.value));
|
|
43
|
+
return ts.factory.createObjectLiteralExpression(objectProperties, multiLine);
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Create a const declaration with an object literal.
|
|
47
|
+
*/
|
|
48
|
+
export function createConstObject(name, properties, multiLine = true) {
|
|
49
|
+
const objectLiteral = createObjectLiteral(properties, multiLine);
|
|
50
|
+
return ts.factory.createVariableStatement([ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)], ts.factory.createVariableDeclarationList([ts.factory.createVariableDeclaration(ts.factory.createIdentifier(name), undefined, undefined, objectLiteral)], ts.NodeFlags.Const));
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Create a declare const statement with a typed object.
|
|
54
|
+
*/
|
|
55
|
+
export function createDeclareConstWithType(name, type) {
|
|
56
|
+
return ts.factory.createVariableStatement([ts.factory.createModifier(ts.SyntaxKind.ExportKeyword), ts.factory.createModifier(ts.SyntaxKind.DeclareKeyword)], ts.factory.createVariableDeclarationList([ts.factory.createVariableDeclaration(ts.factory.createIdentifier(name), undefined, type, undefined)], ts.NodeFlags.Const));
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Create a type alias declaration.
|
|
60
|
+
*/
|
|
61
|
+
export function createTypeAlias(name, type) {
|
|
62
|
+
return ts.factory.createTypeAliasDeclaration([ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)], ts.factory.createIdentifier(name), undefined, type);
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Create a type literal with property signatures.
|
|
66
|
+
*/
|
|
67
|
+
export function createTypeLiteral(properties) {
|
|
68
|
+
const members = properties.map((p) => ts.factory.createPropertySignature(undefined, ts.factory.createIdentifier(p.name), p.optional ? ts.factory.createToken(ts.SyntaxKind.QuestionToken) : undefined, p.type));
|
|
69
|
+
return ts.factory.createTypeLiteralNode(members);
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Create an import type declaration.
|
|
73
|
+
*/
|
|
74
|
+
export function createImportType(names, from) {
|
|
75
|
+
const importSpecifiers = names.map((name) => ts.factory.createImportSpecifier(false, undefined, ts.factory.createIdentifier(name)));
|
|
76
|
+
return ts.factory.createImportDeclaration(undefined, ts.factory.createImportClause(true, // isTypeOnly
|
|
77
|
+
undefined, ts.factory.createNamedImports(importSpecifiers)), ts.factory.createStringLiteral(from));
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Parse a type string into a TypeNode.
|
|
81
|
+
*/
|
|
82
|
+
export function parseTypeString(typeStr) {
|
|
83
|
+
// Handle common types
|
|
84
|
+
switch (typeStr) {
|
|
85
|
+
case 'string':
|
|
86
|
+
return ts.factory.createKeywordTypeNode(ts.SyntaxKind.StringKeyword);
|
|
87
|
+
case 'number':
|
|
88
|
+
return ts.factory.createKeywordTypeNode(ts.SyntaxKind.NumberKeyword);
|
|
89
|
+
case 'boolean':
|
|
90
|
+
return ts.factory.createKeywordTypeNode(ts.SyntaxKind.BooleanKeyword);
|
|
91
|
+
case 'any':
|
|
92
|
+
return ts.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword);
|
|
93
|
+
case 'null':
|
|
94
|
+
return ts.factory.createLiteralTypeNode(ts.factory.createNull());
|
|
95
|
+
case 'undefined':
|
|
96
|
+
return ts.factory.createKeywordTypeNode(ts.SyntaxKind.UndefinedKeyword);
|
|
97
|
+
}
|
|
98
|
+
// Handle array types like "string[]" or "User[]"
|
|
99
|
+
if (typeStr.endsWith('[]')) {
|
|
100
|
+
const elementType = parseTypeString(typeStr.slice(0, -2));
|
|
101
|
+
return ts.factory.createArrayTypeNode(elementType);
|
|
102
|
+
}
|
|
103
|
+
// Handle union types like "string | null"
|
|
104
|
+
if (typeStr.includes(' | ')) {
|
|
105
|
+
const types = typeStr.split(' | ').map((t) => parseTypeString(t.trim()));
|
|
106
|
+
return ts.factory.createUnionTypeNode(types);
|
|
107
|
+
}
|
|
108
|
+
// Handle Record<K, V>
|
|
109
|
+
const recordMatch = typeStr.match(/^Record<([^,]+),\s*([^>]+)>$/);
|
|
110
|
+
if (recordMatch) {
|
|
111
|
+
const keyType = parseTypeString(recordMatch[1].trim());
|
|
112
|
+
const valueType = parseTypeString(recordMatch[2].trim());
|
|
113
|
+
return ts.factory.createTypeReferenceNode(ts.factory.createIdentifier('Record'), [keyType, valueType]);
|
|
114
|
+
}
|
|
115
|
+
// Handle inline object types like "{ key: type; ... }"
|
|
116
|
+
if (typeStr.startsWith('{') && typeStr.endsWith('}')) {
|
|
117
|
+
const inner = typeStr.slice(1, -1).trim();
|
|
118
|
+
if (!inner) {
|
|
119
|
+
return ts.factory.createTypeLiteralNode([]);
|
|
120
|
+
}
|
|
121
|
+
const properties = parseObjectTypeProperties(inner);
|
|
122
|
+
return createTypeLiteral(properties);
|
|
123
|
+
}
|
|
124
|
+
// Default to type reference (custom types like "UserResource")
|
|
125
|
+
return ts.factory.createTypeReferenceNode(ts.factory.createIdentifier(typeStr), undefined);
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Parse object type properties from a string like "key: type; key2: type2"
|
|
129
|
+
*/
|
|
130
|
+
function parseObjectTypeProperties(inner) {
|
|
131
|
+
const properties = [];
|
|
132
|
+
let depth = 0;
|
|
133
|
+
let current = '';
|
|
134
|
+
let i = 0;
|
|
135
|
+
while (i < inner.length) {
|
|
136
|
+
const ch = inner[i];
|
|
137
|
+
if (ch === '{' || ch === '<' || ch === '(')
|
|
138
|
+
depth++;
|
|
139
|
+
else if (ch === '}' || ch === '>' || ch === ')')
|
|
140
|
+
depth--;
|
|
141
|
+
if ((ch === ';' || ch === ',') && depth === 0) {
|
|
142
|
+
const prop = parsePropertyString(current.trim());
|
|
143
|
+
if (prop)
|
|
144
|
+
properties.push(prop);
|
|
145
|
+
current = '';
|
|
146
|
+
}
|
|
147
|
+
else {
|
|
148
|
+
current += ch;
|
|
149
|
+
}
|
|
150
|
+
i++;
|
|
151
|
+
}
|
|
152
|
+
// Handle last property
|
|
153
|
+
const lastProp = parsePropertyString(current.trim());
|
|
154
|
+
if (lastProp)
|
|
155
|
+
properties.push(lastProp);
|
|
156
|
+
return properties;
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Parse a single property string like "key: type" or "key?: type"
|
|
160
|
+
*/
|
|
161
|
+
function parsePropertyString(propStr) {
|
|
162
|
+
if (!propStr)
|
|
163
|
+
return null;
|
|
164
|
+
const match = propStr.match(/^([A-Za-z0-9_]+)(\?)?:\s*(.+)$/);
|
|
165
|
+
if (!match)
|
|
166
|
+
return null;
|
|
167
|
+
const [, name, optional, typeStr] = match;
|
|
168
|
+
return {
|
|
169
|
+
name,
|
|
170
|
+
type: parseTypeString(typeStr.trim()),
|
|
171
|
+
optional: !!optional,
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Create an export default statement.
|
|
176
|
+
*/
|
|
177
|
+
export function createExportDefault(expression) {
|
|
178
|
+
return ts.factory.createExportAssignment(undefined, false, expression);
|
|
179
|
+
}
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"prettier": "@aniftyco/prettier",
|
|
4
4
|
"description": "Ferries Laravel types to your TypeScript frontend",
|
|
5
5
|
"type": "module",
|
|
6
|
-
"version": "0.1.
|
|
6
|
+
"version": "0.1.4",
|
|
7
7
|
"repository": "https://github.com/aniftyco/vite-plugin-ferry",
|
|
8
8
|
"main": "dist/index.js",
|
|
9
9
|
"types": "dist/index.d.ts",
|
|
@@ -13,13 +13,21 @@
|
|
|
13
13
|
"scripts": {
|
|
14
14
|
"start": "tsc --watch",
|
|
15
15
|
"build": "rm -rf dist/ && tsc",
|
|
16
|
-
"
|
|
16
|
+
"test": "vitest run",
|
|
17
|
+
"test:watch": "vitest"
|
|
18
|
+
},
|
|
19
|
+
"dependencies": {
|
|
20
|
+
"php-parser": "^3.2.5"
|
|
17
21
|
},
|
|
18
22
|
"devDependencies": {
|
|
19
23
|
"@aniftyco/prettier": "^1.3.0",
|
|
20
24
|
"@types/node": "^24",
|
|
21
25
|
"prettier": "^3.6.2",
|
|
22
26
|
"typescript": "^5.9.2",
|
|
23
|
-
"vite": "^7.3.0"
|
|
27
|
+
"vite": "^7.3.0",
|
|
28
|
+
"vitest": "^4.0.16"
|
|
29
|
+
},
|
|
30
|
+
"peerDependencies": {
|
|
31
|
+
"typescript": "^5.0.0"
|
|
24
32
|
}
|
|
25
33
|
}
|