@se-studio/project-build 1.0.55 → 1.0.58

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/CHANGELOG.md CHANGED
@@ -1,5 +1,23 @@
1
1
  # @se-studio/project-build
2
2
 
3
+ ## 1.0.58
4
+
5
+ ### Patch Changes
6
+
7
+ - Bulk version bump: patch for all packages
8
+
9
+ ## 1.0.57
10
+
11
+ ### Patch Changes
12
+
13
+ - Bulk version bump: patch for all packages
14
+
15
+ ## 1.0.56
16
+
17
+ ### Patch Changes
18
+
19
+ - Bulk version bump: patch for all packages
20
+
3
21
  ## 1.0.55
4
22
 
5
23
  ### Patch Changes
package/dist/index.d.ts CHANGED
@@ -13,7 +13,5 @@
13
13
  *
14
14
  * @packageDocumentation
15
15
  */
16
- export * from './management/index.js';
17
- export * from './tailwind/index.js';
18
16
  export { cleanColourName } from './tailwind-utils.js';
19
17
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,cAAc,uBAAuB,CAAC;AAEtC,cAAc,qBAAqB,CAAC;AAEpC,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC"}
package/dist/index.js CHANGED
@@ -13,8 +13,5 @@
13
13
  *
14
14
  * @packageDocumentation
15
15
  */
16
- export * from './management/index.js';
17
- // Main package index
18
- export * from './tailwind/index.js';
19
16
  export { cleanColourName } from './tailwind-utils.js';
20
17
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,cAAc,uBAAuB,CAAC;AACtC,qBAAqB;AACrB,cAAc,qBAAqB,CAAC;AAEpC,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=generateVisibilityJson.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generateVisibilityJson.d.ts","sourceRoot":"","sources":["../../src/management/generateVisibilityJson.ts"],"names":[],"mappings":""}
@@ -0,0 +1,149 @@
1
+ #!/usr/bin/env node
2
+ /** biome-ignore-all lint/suspicious/noConsole: Console is ok */
3
+ import * as fs from 'node:fs';
4
+ import * as path from 'node:path';
5
+ import { Node, Project, SyntaxKind } from 'ts-morph';
6
+ // Simple argument parsing
7
+ const args = process.argv.slice(2);
8
+ const projectIndex = args.indexOf('--project');
9
+ const projectPath = projectIndex !== -1 ? args[projectIndex + 1] : process.cwd();
10
+ if (!projectPath) {
11
+ console.error('Please specify a project path using --project or run from the project directory.');
12
+ process.exit(1);
13
+ }
14
+ const absoluteProjectPath = path.resolve(projectPath);
15
+ console.log(`Scanning project at: ${absoluteProjectPath}`);
16
+ const project = new Project({
17
+ tsConfigFilePath: path.join(absoluteProjectPath, 'tsconfig.json'),
18
+ skipAddingFilesFromTsConfig: true,
19
+ });
20
+ // Add source files from src/project
21
+ const pattern = path.join(absoluteProjectPath, 'src/project/**/*.{ts,tsx}');
22
+ project.addSourceFilesAtPaths(pattern);
23
+ console.log(`Found ${project.getSourceFiles().length} source files.`);
24
+ const visibilityConfig = {
25
+ components: {},
26
+ collections: {},
27
+ };
28
+ function resolveStringArray(node) {
29
+ if (!node)
30
+ return [];
31
+ // If it's a variable identifier, go to definition
32
+ if (Node.isIdentifier(node)) {
33
+ const definitions = node.getDefinitions();
34
+ for (const def of definitions) {
35
+ const declaration = def.getDeclarationNode();
36
+ if (declaration && Node.isVariableDeclaration(declaration)) {
37
+ const initializer = declaration.getInitializer();
38
+ return resolveStringArray(initializer);
39
+ }
40
+ }
41
+ }
42
+ // If it's a new Set([...])
43
+ if (Node.isNewExpression(node)) {
44
+ const expression = node.getExpression();
45
+ if (expression.getText() === 'Set') {
46
+ const args = node.getArguments();
47
+ if (args.length > 0) {
48
+ return resolveStringArray(args[0]);
49
+ }
50
+ }
51
+ }
52
+ // If it's an array literal [...]
53
+ if (Node.isArrayLiteralExpression(node)) {
54
+ let result = [];
55
+ for (const element of node.getElements()) {
56
+ if (Node.isStringLiteral(element)) {
57
+ result.push(element.getLiteralValue());
58
+ }
59
+ else if (Node.isSpreadElement(element)) {
60
+ // Handle ...FIELD_KEYS
61
+ const expression = element.getExpression();
62
+ result = [...result, ...resolveStringArray(expression)];
63
+ }
64
+ else if (Node.isIdentifier(element)) {
65
+ // Handle variable inside array
66
+ result = [...result, ...resolveStringArray(element)];
67
+ }
68
+ else if (element.getKind() === SyntaxKind.AsExpression) {
69
+ // Handle 'foo' as const
70
+ const expr = element.asKind(SyntaxKind.AsExpression);
71
+ if (expr) {
72
+ const subExpr = expr.getExpression();
73
+ if (Node.isStringLiteral(subExpr)) {
74
+ result.push(subExpr.getLiteralValue());
75
+ }
76
+ }
77
+ }
78
+ }
79
+ return result;
80
+ }
81
+ // Handle 'as const' expression for arrays
82
+ if (Node.isAsExpression(node)) {
83
+ return resolveStringArray(node.getExpression());
84
+ }
85
+ return [];
86
+ }
87
+ function resolveProperty(objectLiteral, propertyName) {
88
+ const property = objectLiteral.getProperty(propertyName);
89
+ if (!property)
90
+ return undefined;
91
+ if (Node.isPropertyAssignment(property)) {
92
+ return property.getInitializer();
93
+ }
94
+ // Handle shorthand property assignment if needed, though less likely for config objects
95
+ if (Node.isShorthandPropertyAssignment(property)) {
96
+ return property.getNameNode();
97
+ }
98
+ return undefined;
99
+ }
100
+ const sourceFiles = project.getSourceFiles();
101
+ for (const sourceFile of sourceFiles) {
102
+ const variableDeclarations = sourceFile.getVariableDeclarations();
103
+ for (const varDecl of variableDeclarations) {
104
+ const name = varDecl.getName();
105
+ if (name.endsWith('Registration')) {
106
+ const initializer = varDecl.getInitializer();
107
+ if (Node.isCallExpression(initializer)) {
108
+ const expression = initializer.getExpression();
109
+ const callName = expression.getText(); // e.g., defineComponent or defineCollection
110
+ if (callName === 'defineComponent' || callName === 'defineCollection') {
111
+ const args = initializer.getArguments();
112
+ if (args.length > 0 && Node.isObjectLiteralExpression(args[0])) {
113
+ const configObject = args[0];
114
+ // Extract Name
115
+ const nameNode = resolveProperty(configObject, 'name');
116
+ let configName = '';
117
+ if (nameNode && Node.isStringLiteral(nameNode)) {
118
+ configName = nameNode.getLiteralValue();
119
+ }
120
+ // Extract usedFields
121
+ const usedFieldsNode = resolveProperty(configObject, 'usedFields');
122
+ const usedFields = resolveStringArray(usedFieldsNode);
123
+ if (configName) {
124
+ if (callName === 'defineComponent') {
125
+ visibilityConfig.components[configName] = usedFields;
126
+ }
127
+ else {
128
+ const collectionEntry = {
129
+ fields: usedFields,
130
+ };
131
+ // Extract cardUsedFields if collection
132
+ const cardUsedFieldsNode = resolveProperty(configObject, 'cardUsedFields');
133
+ if (cardUsedFieldsNode) {
134
+ const cardUsedFields = resolveStringArray(cardUsedFieldsNode);
135
+ collectionEntry.cardFields = cardUsedFields;
136
+ }
137
+ visibilityConfig.collections[configName] = collectionEntry;
138
+ }
139
+ }
140
+ }
141
+ }
142
+ }
143
+ }
144
+ }
145
+ }
146
+ const outputPath = path.join(absoluteProjectPath, 'visibility.json');
147
+ fs.writeFileSync(outputPath, JSON.stringify(visibilityConfig, null, 2));
148
+ console.log(`Visibility JSON written to: ${outputPath}`);
149
+ //# sourceMappingURL=generateVisibilityJson.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generateVisibilityJson.js","sourceRoot":"","sources":["../../src/management/generateVisibilityJson.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@se-studio/project-build",
3
- "version": "1.0.55",
3
+ "version": "1.0.58",
4
4
  "description": "Build tools and management scripts for SE Studio projects",
5
5
  "repository": {
6
6
  "type": "git",
@@ -28,7 +28,8 @@
28
28
  "bin": {
29
29
  "setailwind": "./dist/setailwind.js",
30
30
  "setup-colours": "./dist/management/setupColours.js",
31
- "seskills": "./dist/seskills.js"
31
+ "seskills": "./dist/seskills.js",
32
+ "generate-visibility-json": "./dist/management/generateVisibilityJson.js"
32
33
  },
33
34
  "files": [
34
35
  "dist",
@@ -53,18 +54,19 @@
53
54
  "url": "https://github.com/Something-Else-Studio/se-core-product/issues"
54
55
  },
55
56
  "dependencies": {
56
- "@biomejs/biome": "^2.3.12",
57
+ "@biomejs/biome": "^2.3.13",
57
58
  "@biomejs/js-api": "^4.0.0",
58
- "@biomejs/wasm-nodejs": "^2.3.12",
59
+ "@biomejs/wasm-nodejs": "^2.3.13",
59
60
  "change-case": "^5.4.4",
60
61
  "chroma-js": "^3.2.0",
61
- "contentful-management": "^11.68.0",
62
- "dotenv": "^17.2.3"
62
+ "contentful-management": "^11.68.1",
63
+ "dotenv": "^17.2.3",
64
+ "ts-morph": "27.0.2"
63
65
  },
64
66
  "devDependencies": {
65
67
  "@types/chroma-js": "^3.1.2",
66
68
  "@types/node": "^22.19.7",
67
- "contentful": "^11.10.2",
69
+ "contentful": "^11.10.3",
68
70
  "typescript": "^5.9.3"
69
71
  },
70
72
  "scripts": {
@@ -72,6 +74,7 @@
72
74
  "dev": "tsc --project tsconfig.build.json --watch",
73
75
  "type-check": "tsc --noEmit",
74
76
  "lint": "biome lint .",
77
+ "generate-visibility-json": "node ./dist/management/generateVisibilityJson.js",
75
78
  "clean": "rm -rf dist .turbo *.tsbuildinfo"
76
79
  }
77
80
  }