@malloydata/malloy-interfaces 0.0.241 → 0.0.242-dev250313012122

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@malloydata/malloy-interfaces",
3
- "version": "0.0.241",
3
+ "version": "0.0.242-dev250313012122",
4
4
  "license": "MIT",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -1,43 +1,37 @@
1
- import * as fs from 'fs';
2
-
3
- // eslint-disable-next-line no-console
4
- console.log(`/*
1
+ /* eslint-disable no-console */
2
+ /*
5
3
  * Copyright (c) Meta Platforms, Inc. and affiliates.
6
4
  *
7
5
  * This source code is licensed under the MIT license found in the
8
6
  * LICENSE file in the root directory of this source tree.
9
7
  */
10
- /*
11
- * Autogenerated.
12
- * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
13
- */`);
8
+ import * as fs from 'fs';
14
9
 
15
10
  function snakeToCamel(m: string) {
16
- return m.replace(/_([a-z])/g, g => g[1].toUpperCase());
11
+ const uncapped = m
12
+ .replace(/_([a-z])/g, g => g[1].toUpperCase())
13
+ .replace(/json/g, 'JSON')
14
+ .replace(/sql/g, 'SQL');
15
+ return uncapped[0].toUpperCase() + uncapped.slice(1);
17
16
  }
18
17
 
19
- function fixEnum(m: string) {
20
- m = m.replace(/enum ([A-Za-z]+)Type {/, 'type $1Type = ');
21
- return m.replace(/ {2}[A-Za-z]+With[A-Za-z_]+ = ("[a-z_]+"),?\n}?/g, '| $1');
22
- }
18
+ type MalloyInterfaceFieldType = {
19
+ type: string;
20
+ optional: boolean;
21
+ array: boolean;
22
+ };
23
23
 
24
- function fixEnum2(m: string) {
25
- m = m.replace(/export enum ([A-Za-z_]+) {\n/g, 'export type $1 =');
26
- m = m.replace(/ {2}([A-Z_]+) = \d+,?\n/g, m =>
27
- m.replace(/ {2}([A-Z_]+) = \d+,?\n/, '| "$1"').toLowerCase()
28
- );
29
- return m.replace(/\}/, '');
30
- }
24
+ type MalloyInterfaceType =
25
+ | {
26
+ name: string;
27
+ type: 'struct';
28
+ fields: Record<string, MalloyInterfaceFieldType>;
29
+ }
30
+ | {name: string; type: 'union'; options: Record<string, string>}
31
+ | {name: string; type: 'enum'; values: string[]};
31
32
 
32
- function fixUnionType(m: string) {
33
- m = m.replace(/\n {2}(__type: [A-Za-z_]+Type.[A-Za-z_]+);\n/, '$1} &');
34
- m = m.replace(/ {2}[a-z_]+\?: undefined;\n/g, '');
35
- m = m.replace(/ {2}[a-z_]+: ([A-Za-z_]+);\n/, ' $1');
36
- m = m.replace(/}$/, ';');
37
- return m;
38
- }
33
+ const types: Record<string, MalloyInterfaceType> = {};
39
34
 
40
- let allTypes = '';
41
35
  for (const file of fs.readdirSync('./generated-types')) {
42
36
  if (file === 'index.ts') continue;
43
37
  const text = fs.readFileSync(`./generated-types/${file}`, 'utf8');
@@ -46,44 +40,175 @@ for (const file of fs.readdirSync('./generated-types')) {
46
40
  const firstNonTypeLine = lines.findIndex(
47
41
  line => line.endsWith('Args;') || line.endsWith('Args {')
48
42
  );
49
- let actualTypes = lines.slice(firstTypeLine, firstNonTypeLine).join('\n');
50
- actualTypes = actualTypes.replace(
51
- /export interface I([A-Za-z_]+) {/g,
52
- 'export type $1 = {'
43
+ const actualTypes = lines.slice(firstTypeLine, firstNonTypeLine).join('\n');
44
+ const isAnEnum = actualTypes.match(
45
+ /export enum ([A-Za-z]+) {\n( {4}([A-Z_]+) = \d+,?\n)+}/
53
46
  );
54
- actualTypes = actualTypes.replace(/([A-Za-z]+)\.I\1/g, '$1');
55
- actualTypes = actualTypes.replace(/([A-Za-z]+)\.\1/g, '$1');
56
- actualTypes = actualTypes.replace(/= I/g, '= ');
57
- actualTypes = actualTypes.replace(/\| I/g, '| ');
58
- actualTypes = actualTypes.replace(/ {4}/g, ' ');
59
- actualTypes = actualTypes.replace(
60
- /enum ([A-Za-z]+)Type {\n( {2}\1With([A-Za-z_]+) = "[a-z_]+",?\n)+}/g,
61
- fixEnum
47
+ if (isAnEnum) {
48
+ const name = isAnEnum[1];
49
+ const values: string[] = [];
50
+ const matches = actualTypes.matchAll(/ {4}([A-Z_]+) = \d+/g);
51
+ for (const match of matches) {
52
+ values.push(match[1].toLowerCase());
53
+ }
54
+ types[name] = {
55
+ type: 'enum',
56
+ name,
57
+ values,
58
+ };
59
+ continue;
60
+ }
61
+ const isUnion = actualTypes.match(
62
+ /export enum ([A-Za-z]+)Type {\n(?: {4}[A-Za-z]+With[A-Za-z_]+ = "([a-z_]+)",?\n)+}/
62
63
  );
63
- actualTypes = actualTypes.replace(
64
- /export type ([A-Za-z]+)With([A-Za-z_]+) = {\n {2}(__type: \1Type.\1With\2);\n( {2}[a-z_]+\?: undefined;\n)*( {2}[a-z_]+: [A-Za-z_]+;\n)( {2}[a-z_]+\?: undefined;\n)*}/g,
65
- fixUnionType
66
- );
67
- actualTypes = actualTypes.replace(
68
- /__type: ([A-Za-z]+)Type\.\1With[A-Za-z_]+/g,
69
- m =>
70
- m
71
- .replace(
72
- /__type: [A-Za-z]+Type\.[A-Za-z]+With([A-Za-z_]+)/,
73
- '__type: "$1"'
74
- )
75
- .toLowerCase()
76
- );
77
- actualTypes = actualTypes.replace(
78
- /export enum ([A-Za-z_]+) {\n( {2}[A-Z_]+ = \d+,?\n)+}/g,
79
- fixEnum2
80
- );
81
- actualTypes = actualTypes.replace(/Json/g, 'JSON');
82
- actualTypes = actualTypes.replace(/Sql/g, 'SQL');
83
- actualTypes = actualTypes.replace(/__type/g, 'kind');
84
- actualTypes = actualTypes.replace(/With[A-Za-z_]+/g, snakeToCamel);
85
- allTypes += actualTypes + '\n';
64
+ if (isUnion) {
65
+ const name = isUnion[1];
66
+ const options: Record<string, string> = {};
67
+ const optionMatches = actualTypes.matchAll(
68
+ / {4}([a-z_]+): ([A-Za-z]+).I[A-Za-z]+;/g
69
+ );
70
+ for (const optionMatch of optionMatches) {
71
+ const [name, type] = [optionMatch[1], optionMatch[2]];
72
+ options[name] = type;
73
+ }
74
+ types[name] = {
75
+ type: 'union',
76
+ name,
77
+ options,
78
+ };
79
+ continue;
80
+ }
81
+ // ... for "clarity"
82
+ const isStruct = true;
83
+ if (isStruct) {
84
+ const nameMatch = actualTypes.match(/export interface I([A-Za-z]+) {/)!;
85
+ const name = nameMatch[1];
86
+ const fields: Record<string, MalloyInterfaceFieldType> = {};
87
+ const fieldMatches = actualTypes.matchAll(
88
+ / {4}([a-z_]+)(\?)?: (?:([a-z]+)|([A-Za-z]+)\.[A-Za-z]+|(?:Array<([a-z]+)>)|(?:Array<([A-Za-z]+)\.[A-Za-z]+>));/g
89
+ );
90
+ for (const fieldMatch of fieldMatches) {
91
+ const [
92
+ name,
93
+ optionalQ,
94
+ basicType,
95
+ specialType,
96
+ arrayBasicType,
97
+ arraySpecialType,
98
+ ] = [
99
+ fieldMatch[1],
100
+ fieldMatch[2],
101
+ fieldMatch[3],
102
+ fieldMatch[4],
103
+ fieldMatch[5],
104
+ fieldMatch[6],
105
+ ];
106
+ const optional = optionalQ === '?';
107
+ const type =
108
+ (basicType && {type: basicType, optional, array: false}) ??
109
+ (specialType && {type: specialType, optional, array: false}) ??
110
+ (arrayBasicType && {
111
+ type: arrayBasicType,
112
+ array: true,
113
+ optional,
114
+ }) ??
115
+ (arraySpecialType && {
116
+ type: arraySpecialType,
117
+ array: true,
118
+ optional,
119
+ });
120
+ if (!type) throw new Error(`Invalid type ${fieldMatch[0]}`);
121
+ fields[name] = type;
122
+ }
123
+ types[name] = {
124
+ type: 'struct',
125
+ name,
126
+ fields,
127
+ };
128
+ }
129
+ }
130
+
131
+ console.log(`/*
132
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
133
+ *
134
+ * This source code is licensed under the MIT license found in the
135
+ * LICENSE file in the root directory of this source tree.
136
+ */
137
+ /*
138
+ * Autogenerated.
139
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
140
+ */
141
+
142
+ type MalloyInterfaceFieldType = {
143
+ type: string;
144
+ optional: boolean;
145
+ array: boolean;
146
+ };
147
+
148
+ type MalloyInterfaceType =
149
+ | {
150
+ name: string;
151
+ type: 'struct';
152
+ fields: Record<string, MalloyInterfaceFieldType>;
153
+ }
154
+ | {name: string; type: 'union'; options: Record<string, string>}
155
+ | {name: string; type: 'enum'; values: string[]};
156
+ `);
157
+
158
+ console.log(
159
+ `export const MALLOY_INTERFACE_TYPES: Record<string, MalloyInterfaceType> = ${JSON.stringify(
160
+ types,
161
+ null,
162
+ 2
163
+ )
164
+ .replace(/"/g, "'")
165
+ .replace(/'\n/g, "',\n")
166
+ .replace(/true\n/g, 'true,\n')
167
+ .replace(/false\n/g, 'false,\n')
168
+ .replace(/}\n/g, '},\n')}\n`
169
+ );
170
+
171
+ for (const typeName in types) {
172
+ const type = types[typeName];
173
+ if (type.type === 'enum') {
174
+ console.log(
175
+ `export type ${type.name} = ${type.values
176
+ .map(v => `'${v}'`)
177
+ .join(' | ')};\n`
178
+ );
179
+ } else if (type.type === 'struct') {
180
+ console.log(`export type ${type.name} = {
181
+ ${Object.entries(type.fields)
182
+ .map(
183
+ ([name, field]) =>
184
+ ` ${name}${
185
+ field.optional ? '?' : ''
186
+ }: ${malloyInterfaceFieldTypeToString(field)};`
187
+ )
188
+ .join('\n')}
189
+ }\n`);
190
+ } else if (type.type === 'union') {
191
+ console.log(
192
+ `export type ${type.name}Type = ${Object.keys(type.options)
193
+ .map(kind => `'${kind}'`)
194
+ .join(' | ')};\n`
195
+ );
196
+ console.log(
197
+ `export type ${type.name} = ${Object.keys(type.options)
198
+ .map(kind => `${type.name}With${snakeToCamel(kind)}`)
199
+ .join(' | ')};\n`
200
+ );
201
+ for (const kind in type.options) {
202
+ const childType = type.options[kind];
203
+ console.log(
204
+ `export type ${type.name}With${snakeToCamel(
205
+ kind
206
+ )} = {kind: '${kind}'} & ${childType};\n`
207
+ );
208
+ }
209
+ }
86
210
  }
87
211
 
88
- // eslint-disable-next-line no-console
89
- console.log(allTypes);
212
+ function malloyInterfaceFieldTypeToString(type: MalloyInterfaceFieldType) {
213
+ return type.array ? `Array<${type.type}>` : type.type;
214
+ }