Skip to content

Commit fde779c

Browse files
committed
updates
1 parent c772ab9 commit fde779c

File tree

6 files changed

+226
-203
lines changed

6 files changed

+226
-203
lines changed

.eslintrc.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ module.exports = {
3232
'files': ['lib/**/*.ts', 'src/**/*.ts'],
3333
'excludedFiles': [
3434
'**/platform_support.ts',
35+
'**/common_exports.ts',
36+
'**/export_types.ts',
3537
'**/*.spec.ts',
3638
'**/*.test.ts',
3739
'**/*.tests.ts',

.platform-isolation.config.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ module.exports = {
1515
exclude: [
1616
// Platform definition file (this file defines Platform type, doesn't need __platforms)
1717
'**/platform_support.ts',
18+
19+
'**/common_exports.ts',
20+
'**/export_types.ts',
1821

1922
// Test files
2023
'**/*.spec.ts',

lib/common_exports.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,5 +38,3 @@ export {
3838
export { NOTIFICATION_TYPES, DECISION_NOTIFICATION_TYPES } from './notification_center/type';
3939

4040
export { OptimizelyDecideOption } from './shared_types';
41-
42-
export const __platforms: Platform[] = ['__universal__'];

lib/export_types.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,5 +106,3 @@ export type {
106106
NotificationCenter,
107107
OptimizelySegmentOption,
108108
} from './shared_types';
109-
110-
export const __platforms: Platform[] = ['__universal__'];

scripts/platform-utils.js

Lines changed: 110 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
/* eslint-disable @typescript-eslint/no-var-requires */
2+
/* eslint-disable no-inner-declarations */
13
/**
24
* Platform Utilities
35
*
@@ -55,6 +57,9 @@ function getValidPlatforms(workspaceRoot) {
5557
platforms.push(type.literal.text);
5658
}
5759
}
60+
} else if (ts.isLiteralTypeNode(node.type) && ts.isStringLiteral(node.type.literal)) {
61+
// Handle single literal type: type Platform = 'browser';
62+
platforms.push(node.type.literal.text);
5863
}
5964
}
6065

@@ -77,21 +82,27 @@ function getValidPlatforms(workspaceRoot) {
7782
}
7883

7984
/**
80-
* Extracts __platforms array from TypeScript AST
85+
* Extracts __platforms array from TypeScript AST with detailed error reporting
8186
*
82-
* Returns:
83-
* - string[] if valid platforms array found
84-
* - 'NOT_CONST' if __platforms is not declared as const
85-
* - 'NOT_LITERALS' if array contains non-literal values
86-
* - null if __platforms export not found
87+
* Returns an object with:
88+
* - success: boolean - whether extraction was successful
89+
* - platforms: string[] - array of platform values (if successful)
90+
* - error: object - detailed error information (if unsuccessful)
91+
* - type: 'MISSING' | 'NOT_CONST' | 'NOT_ARRAY' | 'EMPTY_ARRAY' | 'NOT_LITERALS' | 'INVALID_VALUES'
92+
* - message: string - human-readable error message
93+
* - invalidValues: string[] - list of invalid platform values (for INVALID_VALUES type)
8794
*
8895
* @param {ts.SourceFile} sourceFile - TypeScript source file AST
89-
* @returns {string[] | 'NOT_CONST' | 'NOT_LITERALS' | null}
96+
* @param {string} filePath - File path for context in error messages
97+
* @param {string[]} validPlatforms - Array of valid platform values
98+
* @returns {Object}
9099
*/
91-
function extractPlatformsFromAST(sourceFile) {
92-
let platforms = null;
100+
function extractPlatformsFromAST(sourceFile, filePath, validPlatforms) {
101+
let found = false;
102+
let isConst = false;
103+
let isArray = false;
104+
let platforms = [];
93105
let hasNonStringLiteral = false;
94-
let isNotConst = false;
95106

96107
function visit(node) {
97108
// Look for: export const __platforms = [...]
@@ -102,17 +113,15 @@ function extractPlatformsFromAST(sourceFile) {
102113
);
103114

104115
if (hasExport) {
105-
// Check if declaration is const
106-
const isConst = (node.declarationList.flags & ts.NodeFlags.Const) !== 0;
116+
const isConstDecl = (node.declarationList.flags & ts.NodeFlags.Const) !== 0;
107117

108118
for (const declaration of node.declarationList.declarations) {
109119
if (ts.isVariableDeclaration(declaration) &&
110120
ts.isIdentifier(declaration.name) &&
111121
declaration.name.text === '__platforms') {
112122

113-
if (!isConst) {
114-
isNotConst = true;
115-
}
123+
found = true;
124+
isConst = isConstDecl;
116125

117126
let initializer = declaration.initializer;
118127

@@ -126,9 +135,11 @@ function extractPlatformsFromAST(sourceFile) {
126135
initializer = initializer.expression;
127136
}
128137

129-
// Extract array elements
138+
// Check if it's an array
130139
if (initializer && ts.isArrayLiteralExpression(initializer)) {
131-
platforms = [];
140+
isArray = true;
141+
142+
// Extract array elements
132143
for (const element of initializer.elements) {
133144
if (ts.isStringLiteral(element)) {
134145
platforms.push(element.text);
@@ -137,8 +148,9 @@ function extractPlatformsFromAST(sourceFile) {
137148
hasNonStringLiteral = true;
138149
}
139150
}
140-
return; // Found it, stop visiting
141151
}
152+
153+
return; // Found it, stop visiting
142154
}
143155
}
144156
}
@@ -149,36 +161,104 @@ function extractPlatformsFromAST(sourceFile) {
149161

150162
visit(sourceFile);
151163

152-
if (platforms !== null) {
153-
if (isNotConst) {
154-
return 'NOT_CONST';
155-
}
156-
if (hasNonStringLiteral) {
157-
return 'NOT_LITERALS';
164+
// Detailed error reporting
165+
if (!found) {
166+
return {
167+
success: false,
168+
error: {
169+
type: 'MISSING',
170+
message: `File does not export '__platforms' constant`
171+
}
172+
};
173+
}
174+
175+
if (!isConst) {
176+
return {
177+
success: false,
178+
error: {
179+
type: 'NOT_CONST',
180+
message: `'__platforms' must be declared with 'const', found non-const declaration`
181+
}
182+
};
183+
}
184+
185+
if (!isArray) {
186+
return {
187+
success: false,
188+
error: {
189+
type: 'NOT_ARRAY',
190+
message: `'__platforms' must be an array literal, found ${platforms.length === 0 ? 'non-array value' : 'other type'}`
191+
}
192+
};
193+
}
194+
195+
if (hasNonStringLiteral) {
196+
return {
197+
success: false,
198+
error: {
199+
type: 'NOT_LITERALS',
200+
message: `'__platforms' must only contain string literals, found non-literal values`
201+
}
202+
};
203+
}
204+
205+
if (platforms.length === 0) {
206+
return {
207+
success: false,
208+
error: {
209+
type: 'EMPTY_ARRAY',
210+
message: `'__platforms' array is empty, must contain at least one platform`
211+
}
212+
};
213+
}
214+
215+
// Validate platform values if validPlatforms provided
216+
if (validPlatforms) {
217+
const invalidPlatforms = platforms.filter(p => !validPlatforms.includes(p));
218+
if (invalidPlatforms.length > 0) {
219+
return {
220+
success: false,
221+
error: {
222+
type: 'INVALID_VALUES',
223+
message: `Invalid platform values found`,
224+
invalidValues: invalidPlatforms
225+
}
226+
};
158227
}
159228
}
160229

161-
return platforms;
230+
return {
231+
success: true,
232+
platforms: platforms
233+
};
162234
}
163235

164236
/**
165-
* Extract platforms from a file path
237+
* Extract platforms from a file path with detailed error reporting
166238
*
167239
* @param {string} filePath - Absolute path to the file
168-
* @returns {string[] | 'NOT_CONST' | 'NOT_LITERALS' | null}
240+
* @param {string} workspaceRoot - Workspace root for resolving valid platforms
241+
* @returns {Object} Result object with success, platforms, and error information
169242
*/
170-
function extractPlatformsFromFile(filePath) {
243+
function extractPlatformsFromFile(filePath, workspaceRoot) {
171244
try {
245+
const validPlatforms = workspaceRoot ? getValidPlatforms(workspaceRoot) : null;
172246
const content = fs.readFileSync(filePath, 'utf-8');
173247
const sourceFile = ts.createSourceFile(
174248
filePath,
175249
content,
176250
ts.ScriptTarget.Latest,
177251
true
178252
);
179-
return extractPlatformsFromAST(sourceFile);
253+
return extractPlatformsFromAST(sourceFile, filePath, validPlatforms);
180254
} catch (error) {
181-
return null;
255+
return {
256+
success: false,
257+
error: {
258+
type: 'READ_ERROR',
259+
message: `Failed to read or parse file: ${error.message}`
260+
}
261+
};
182262
}
183263
}
184264

0 commit comments

Comments
 (0)