@webspatial/builder 0.1.19 → 0.1.21

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 CHANGED
@@ -15,6 +15,6 @@ For WebSpatial Builder:
15
15
  For WebSpatial:
16
16
  - [Table of Contents](../../docs/en/README.md)
17
17
  - [Introduction](../../docs/en/introduction/README.md)
18
- - [Quick Start](../../docs/en/quick-start/README.md)
18
+ - [Quick Example](../../docs/en/quick-start/README.md)
19
19
  - [Core Concepts](../../docs/en/core-concepts/README.md)
20
20
  - [Development Guide](../../docs/en/development-guide/README.md)
@@ -28,13 +28,19 @@ function configId(manifestJson, bundleId) {
28
28
  function configStartUrl(manifestJson, base, manifestUrl, isNet) {
29
29
  var _a;
30
30
  let start_url = (_a = manifestJson.start_url) !== null && _a !== void 0 ? _a : '/index.html';
31
+ if (!start_url.match(/\.html(\?|$)/)) {
32
+ const [path, query] = start_url.split('?');
33
+ start_url = path.endsWith('/') ? `${path}index.html` : `${path}/index.html`;
34
+ if (query)
35
+ start_url += `?${query}`;
36
+ }
31
37
  const isStartUrl = (0, validate_1.validateURL)(start_url);
32
38
  const hasBase = base.length > 0;
33
39
  if (hasBase) {
34
40
  const isBaseUrl = (0, validate_1.validateURL)(base);
35
41
  if (!isStartUrl && !isBaseUrl) {
36
42
  const staticWebRoot = (0, path_1.resolve)('./static-web');
37
- const resolvedPath = (0, path_1.resolve)(staticWebRoot, base, start_url);
43
+ const resolvedPath = (0, path_1.join)(base, start_url);
38
44
  const normalizedPath = (0, path_1.normalize)(resolvedPath);
39
45
  const safePath = (0, path_1.join)(staticWebRoot, normalizedPath);
40
46
  start_url = (0, path_1.relative)(process.cwd(), safePath)
@@ -178,7 +178,15 @@ async function checkIcons(manifest, manifestUrl, isDev = false) {
178
178
  // Check if the image is completely opaque
179
179
  if (maxSizeImage && !imageHelper_1.ImageHelper.isFullyOpaque(maxSizeImage)) {
180
180
  if (isDev) {
181
+ manifest.icons = [
182
+ {
183
+ src: (0, path_1.join)(__dirname, '../../assets/icon-default.png'),
184
+ sizes: '1024x1024',
185
+ purpose: 'maskable',
186
+ },
187
+ ];
181
188
  utils_2.CliLog.warn('In the Web Spatial App on VisionPro, the icon must be greater than or equal to 1024x1024, and the purpose parameter must include maskable');
189
+ utils_2.CliLog.warn('No matching icon found, use default icon');
182
190
  return;
183
191
  }
184
192
  throw new CustomError_1.CustomError({
@@ -8,6 +8,7 @@ export declare const WEB_PROJECT_DIRECTORY = "web-spatial/static-web";
8
8
  export declare const ASSET_DIRECTORY = "web-spatial/Assets.xcassets";
9
9
  export declare const BACK_APPICON_DIRECTORY: string;
10
10
  export declare const MIDDLE_APPICON_DIRECTORY: string;
11
+ export declare const LOGO_DIRECTORY: string;
11
12
  export declare class ResourceManager {
12
13
  static moveProjectFrom(dir: string): Promise<void>;
13
14
  static generateIcon(info: ManifestInfo): Promise<Jimp>;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ResourceManager = exports.MIDDLE_APPICON_DIRECTORY = exports.BACK_APPICON_DIRECTORY = exports.ASSET_DIRECTORY = exports.WEB_PROJECT_DIRECTORY = exports.PROJECT_TEST_DIRECTORY = exports.PROJECT_EXPORT_DIRECTORY = exports.PROJECT_BUILD_DIRECTORY = exports.PROJECT_DIRECTORY = void 0;
3
+ exports.ResourceManager = exports.LOGO_DIRECTORY = exports.MIDDLE_APPICON_DIRECTORY = exports.BACK_APPICON_DIRECTORY = exports.ASSET_DIRECTORY = exports.WEB_PROJECT_DIRECTORY = exports.PROJECT_TEST_DIRECTORY = exports.PROJECT_EXPORT_DIRECTORY = exports.PROJECT_BUILD_DIRECTORY = exports.PROJECT_DIRECTORY = void 0;
4
4
  const fs = require("fs");
5
5
  const path_1 = require("path");
6
6
  const file_1 = require("./file");
@@ -16,6 +16,7 @@ exports.BACK_APPICON_DIRECTORY = exports.ASSET_DIRECTORY +
16
16
  '/AppIcon.solidimagestack/Back.solidimagestacklayer/Content.imageset';
17
17
  exports.MIDDLE_APPICON_DIRECTORY = exports.ASSET_DIRECTORY +
18
18
  '/AppIcon.solidimagestack/Middle.solidimagestacklayer/Content.imageset';
19
+ exports.LOGO_DIRECTORY = exports.ASSET_DIRECTORY + '/logo.imageset';
19
20
  const supportPlatform = ['visionos'];
20
21
  class ResourceManager {
21
22
  static async moveProjectFrom(dir) {
@@ -67,12 +68,12 @@ class ResourceManager {
67
68
  if (!hasModule) {
68
69
  (0, child_process_1.execSync)(`cd ${(0, path_1.join)(__dirname, '../../../')} && pnpm add @webspatial/platform-${usePlatform}`);
69
70
  }
70
- let tempDir = (0, path_1.join)(__dirname, `../../temp`);
71
+ let tempDir = './node_modules/.webspatial-builder-temp';
71
72
  let tempPlatformDir = (0, path_1.join)(tempDir, `platform-${usePlatform}`);
72
73
  let tempProjectDir = (0, path_1.join)(tempPlatformDir, './project');
73
74
  let temBuildDir = (0, path_1.join)(tempPlatformDir, './build');
74
75
  let temExportDir = (0, path_1.join)(tempPlatformDir, './export');
75
- let temTestDir = `./node_modules/.webspatial-builder-temp/platform-${usePlatform}/test`;
76
+ let temTestDir = (0, path_1.join)(tempPlatformDir, './test');
76
77
  if (!fs.existsSync(tempDir)) {
77
78
  fs.mkdirSync(tempDir);
78
79
  }
@@ -88,12 +89,6 @@ class ResourceManager {
88
89
  if (!fs.existsSync(temExportDir)) {
89
90
  fs.mkdirSync(temExportDir);
90
91
  }
91
- if (!fs.existsSync('./node_modules/.webspatial-builder-temp')) {
92
- fs.mkdirSync('./node_modules/.webspatial-builder-temp');
93
- }
94
- if (!fs.existsSync(`./node_modules/.webspatial-builder-temp/platform-${usePlatform}`)) {
95
- fs.mkdirSync(`./node_modules/.webspatial-builder-temp/platform-${usePlatform}`);
96
- }
97
92
  if (!fs.existsSync(temTestDir)) {
98
93
  fs.mkdirSync(temTestDir);
99
94
  }
@@ -1 +1 @@
1
- export declare const manifestSwiftTemplate = "\nimport Foundation\n\nvar pwaManager = PWAManager()\n\nstruct PWAManager: Codable {\n var isLocal: Bool = false\n var start_url: String = \"START_URL\"\n var scope: String = \"SCOPE\"\n var id: String = \"AppID\"\n\n var name: String = \"AppName\"\n var short_name: String = \"name\"\n var description: String = \"Description\"\n\n var display: PWADisplayMode = .minimal\n var display_override: [PWADisplayMode] = []\n var protocol_handlers: [PWAProtocol] = [PWAProtocol(protocolValue: \"\", url: \"\")]\n var mainScene: WindowContainerOptions = .init(\n defaultSize: .init(\n width: SceneWidth,\n height: SceneHeight\n ),\n resizability: SceneResizability\n )\n var useMainScene: Bool = USE_MAIN_SCENE\n\n mutating func _init() {\n let urlType = start_url.split(separator: \"://\").first\n if !(urlType == \"http\" || urlType == \"https\") {\n if scope == \"\" || scope == \"/\" {\n scope = \"./\"\n }\n let startUrl = Bundle.main.url(forResource: start_url, withExtension: \"\", subdirectory: \"\")\n start_url = startUrl!.absoluteString\n scope = URL(string: (scope.starts(with: \"/\") ? \"..\" : \"../\") + scope, relativeTo: startUrl)!.absoluteString\n isLocal = true\n }\n\n if display_override.count > 0 {\n display = display_override[0]\n }\n\n for i in 0 ... protocol_handlers.count - 1 {\n let item = protocol_handlers[i]\n protocol_handlers[i].updateUrl(scope + item.url)\n }\n }\n\n func checkInScope(url: String) -> Bool {\n return url.starts(with: scope)\n }\n\n // web+spatial://test\n func checkInDeeplink(url: String) -> String {\n var linkUrl: String = url\n for item in protocol_handlers {\n if linkUrl.starts(with: item.protocolValue) {\n let queryString: String = linkUrl.replacingOccurrences(of: item.protocolValue, with: \"\").addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)!\n linkUrl = item.url.replacingOccurrences(of: \"%s\", with: item.protocolValue + queryString)\n }\n }\n logger.debug(linkUrl)\n return linkUrl\n }\n\n func getLocalResourceURL(url: String) -> String {\n let path = String(url.split(separator: \"file://\").first!.split(separator: \"?\").first!)\n let newUrl = URL(string: url)\n let fileManager = FileManager.default\n if fileManager.fileExists(atPath: newUrl!.path) {\n return url\n }\n var resource: String = Bundle.main.url(forResource: newUrl?.path, withExtension: \"\", subdirectory: \"\")?.absoluteString ?? \"\"\n if resource == \"\" {\n resource = Bundle.main.url(forResource: \"static-web\" + path, withExtension: \"\", subdirectory: \"\")?.absoluteString ?? \"\"\n }\n if resource == \"\" {\n return url\n }\n if newUrl?.query() != nil {\n resource += \"?\" + (newUrl?.query())!\n }\n if newUrl?.fragment() != nil {\n resource += \"#\" + (newUrl?.fragment())!\n }\n return resource\n }\n}\n\nenum PWADisplayMode: Codable {\n case minimal\n case standalone\n case fullscreen\n}\n\nstruct PWAProtocol: Codable {\n var protocolValue: String = \"\"\n var url: String = \"\"\n\n mutating func updateUrl(_ str: String) {\n url = str\n }\n}\n\n";
1
+ export declare const manifestSwiftTemplate = "\nimport Foundation\n\nvar pwaManager = PWAManager()\n\nstruct PWAManager: Codable {\n var isLocal: Bool = false\n var start_url: String = \"START_URL\"\n var scope: String = \"SCOPE\"\n var id: String = \"AppID\"\n\n var name: String = \"AppName\"\n var short_name: String = \"name\"\n var description: String = \"Description\"\n\n var display: PWADisplayMode = .minimal\n var display_override: [PWADisplayMode] = []\n var protocol_handlers: [PWAProtocol] = [PWAProtocol(protocolValue: \"\", url: \"\")]\n var mainScene: WindowContainerOptions = .init(\n defaultSize: .init(\n width: SceneWidth,\n height: SceneHeight\n ),\n resizability: SceneResizability\n )\n var useMainScene: Bool = USE_MAIN_SCENE\n private var version: String = \"PACKAGE_VERSION\"\n\n mutating func _init() {\n let urlType = start_url.split(separator: \"://\").first\n if !(urlType == \"http\" || urlType == \"https\") {\n if scope == \"\" || scope == \"/\" {\n scope = \"./\"\n }\n let startUrl = Bundle.main.url(forResource: start_url, withExtension: \"\", subdirectory: \"\")\n start_url = startUrl!.absoluteString\n scope = URL(string: (scope.starts(with: \"/\") ? \".\" : \"./\") + scope, relativeTo: Bundle.main.executableURL)!.absoluteString\n isLocal = true\n }\n\n if display_override.count > 0 {\n display = display_override[0]\n }\n\n for i in 0 ... protocol_handlers.count - 1 {\n let item = protocol_handlers[i]\n protocol_handlers[i].updateUrl(scope + item.url)\n }\n }\n\n func checkInScope(url: String) -> Bool {\n return url.starts(with: scope)\n }\n\n // web+spatial://test\n func checkInDeeplink(url: String) -> String {\n var linkUrl: String = url\n for item in protocol_handlers {\n if linkUrl.starts(with: item.protocolValue) {\n let queryString: String = linkUrl.replacingOccurrences(of: item.protocolValue, with: \"\").addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)!\n linkUrl = item.url.replacingOccurrences(of: \"%s\", with: item.protocolValue + queryString)\n }\n }\n logger.debug(linkUrl)\n return linkUrl\n }\n\n func getLocalResourceURL(url: String) -> String {\n let path = String(url.split(separator: \"file://\").first!.split(separator: \"?\").first!)\n let newUrl = URL(string: url)\n let fileManager = FileManager.default\n if fileManager.fileExists(atPath: newUrl!.path) {\n return url\n }\n var resource: String = Bundle.main.url(forResource: newUrl?.path, withExtension: \"\", subdirectory: \"\")?.absoluteString ?? \"\"\n if resource == \"\" {\n resource = Bundle.main.url(forResource: \"static-web\" + path, withExtension: \"\", subdirectory: \"\")?.absoluteString ?? \"\"\n }\n if resource == \"\" {\n return url\n }\n if newUrl?.query() != nil {\n resource += \"?\" + (newUrl?.query())!\n }\n if newUrl?.fragment() != nil {\n resource += \"#\" + (newUrl?.fragment())!\n }\n return resource\n }\n \n func getVersion() -> String {\n return version\n }\n}\n\nenum PWADisplayMode: Codable {\n case minimal\n case standalone\n case fullscreen\n}\n\nstruct PWAProtocol: Codable {\n var protocolValue: String = \"\"\n var url: String = \"\"\n\n mutating func updateUrl(_ str: String) {\n url = str\n }\n}\n\n";
@@ -27,6 +27,7 @@ struct PWAManager: Codable {
27
27
  resizability: SceneResizability
28
28
  )
29
29
  var useMainScene: Bool = USE_MAIN_SCENE
30
+ private var version: String = "PACKAGE_VERSION"
30
31
 
31
32
  mutating func _init() {
32
33
  let urlType = start_url.split(separator: "://").first
@@ -36,7 +37,7 @@ struct PWAManager: Codable {
36
37
  }
37
38
  let startUrl = Bundle.main.url(forResource: start_url, withExtension: "", subdirectory: "")
38
39
  start_url = startUrl!.absoluteString
39
- scope = URL(string: (scope.starts(with: "/") ? ".." : "../") + scope, relativeTo: startUrl)!.absoluteString
40
+ scope = URL(string: (scope.starts(with: "/") ? "." : "./") + scope, relativeTo: Bundle.main.executableURL)!.absoluteString
40
41
  isLocal = true
41
42
  }
42
43
 
@@ -89,6 +90,10 @@ struct PWAManager: Codable {
89
90
  }
90
91
  return resource
91
92
  }
93
+
94
+ func getVersion() -> String {
95
+ return version
96
+ }
92
97
  }
93
98
 
94
99
  enum PWADisplayMode: Codable {
@@ -79,7 +79,7 @@ class XcodeProject {
79
79
  this.updateExportOptions();
80
80
  if (option.icon)
81
81
  await this.bindIcon(option.icon);
82
- this.bindManifestInfo(project, option.manifestInfo.json, isDev);
82
+ await this.bindManifestInfo(project, option.manifestInfo.json, isDev);
83
83
  if (option['version']) {
84
84
  this.updateVersion(project, option['version']);
85
85
  }
@@ -169,6 +169,14 @@ class XcodeProject {
169
169
  middleConfig.images[0]['filename'] = middleIconFileName;
170
170
  await middleIcon.writeAsync(middleIconFullPath);
171
171
  await fs.writeFileSync(middleIconConfigPath, JSON.stringify(middleConfig));
172
+ const logoConfigDirectory = (0, path_1.join)(resource_1.PROJECT_DIRECTORY, resource_1.LOGO_DIRECTORY);
173
+ const logoConfigPath = (0, path_1.join)(logoConfigDirectory, 'Contents.json');
174
+ let logoConfig = await (0, load_1.loadJsonFromDisk)(logoConfigPath);
175
+ const logoFileName = 'logo.' + icon.getMIME().replace('image/', '');
176
+ const logoFullPath = (0, path_1.join)(logoConfigDirectory, logoFileName);
177
+ logoConfig.images[0]['filename'] = logoFileName;
178
+ await icon.writeAsync(logoFullPath);
179
+ await fs.writeFileSync(logoConfigPath, JSON.stringify(logoConfig));
172
180
  }
173
181
  }
174
182
  static updateTeamId(xcodeProject, teamId) {
@@ -181,7 +189,7 @@ class XcodeProject {
181
189
  }
182
190
  fs.writeFileSync((0, path_1.join)(resource_1.PROJECT_BUILD_DIRECTORY, 'ExportOptions.plist'), useExportOptionsXML);
183
191
  }
184
- static bindManifestInfo(xcodeProject, manifest, isDev = false) {
192
+ static async bindManifestInfo(xcodeProject, manifest, isDev = false) {
185
193
  var _a;
186
194
  xcodeProject.updateProductName(manifest.name);
187
195
  // set PRODUCT_BUNDLE_IDENTIFIER need ""
@@ -189,7 +197,7 @@ class XcodeProject {
189
197
  xcodeProject.updateBuildProperty('PRODUCT_BUNDLE_IDENTIFIER', `"${manifest.id}"`);
190
198
  }
191
199
  this.updateDeeplink((_a = manifest.protocol_handlers) !== null && _a !== void 0 ? _a : []);
192
- this.modifySwift(manifest);
200
+ await this.modifySwift(manifest);
193
201
  }
194
202
  static updateVersion(xcodeProject, version) {
195
203
  xcodeProject.updateBuildProperty('CURRENT_PROJECT_VERSION', version);
@@ -203,9 +211,13 @@ class XcodeProject {
203
211
  const newInfoPlist = infoPlistXML.replace('DEEPLINK', deeplinkString);
204
212
  fs.writeFileSync(infoPlistPath, newInfoPlist);
205
213
  }
206
- static modifySwift(manifest) {
214
+ static async modifySwift(manifest) {
215
+ var _a;
207
216
  const manifestSwiftPath = (0, path_1.join)(resource_1.PROJECT_DIRECTORY, './web-spatial/libs/webView/manifest.swift');
217
+ const xcodePackageJsonPath = (0, path_1.join)(resource_1.PROJECT_DIRECTORY, 'package.json');
218
+ const packageJson = await (0, load_1.loadJsonFromDisk)(xcodePackageJsonPath);
208
219
  let manifestSwift = manifestSwiftTemplate_1.manifestSwiftTemplate;
220
+ manifestSwift = manifestSwift.replace('PACKAGE_VERSION', (_a = packageJson.version) !== null && _a !== void 0 ? _a : '0.0.0');
209
221
  manifestSwift = manifestSwift.replace('START_URL', manifest.start_url);
210
222
  manifestSwift = manifestSwift.replace('SCOPE', manifest.scope);
211
223
  manifestSwift = manifestSwift.replace('AppName', manifest.name);
@@ -158,10 +158,14 @@ class Xcrun {
158
158
  try {
159
159
  const res = (0, child_process_1.execSync)(buildCMD);
160
160
  if (res.toString().includes('** BUILD FAILED **')) {
161
+ console.log(res.toString());
161
162
  return false;
162
163
  }
163
164
  }
164
- catch (e) { }
165
+ catch (e) {
166
+ console.log(e);
167
+ return false;
168
+ }
165
169
  console.log('------------------- build end -------------------');
166
170
  return true;
167
171
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webspatial/builder",
3
- "version": "0.1.19",
3
+ "version": "0.1.21",
4
4
  "description": "Client CLI tool to Generate XRApp project for Apple Vision Pro",
5
5
  "type": "commonjs",
6
6
  "engines": {
@@ -40,7 +40,7 @@
40
40
  "sharp": "^0.33.5",
41
41
  "valid-url": "^1.0.9",
42
42
  "xcode": "^3.0.1",
43
- "@webspatial/platform-visionos": "^0.1.19"
43
+ "@webspatial/platform-visionos": "^0.1.21"
44
44
  },
45
45
  "devDependencies": {
46
46
  "@rollup/plugin-terser": "^0.4.3",