@wp-typia/create-workspace-template 0.13.0 → 0.14.0

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.
@@ -30,6 +30,7 @@ wp-typia add pattern hero-layout
30
30
  ## Development
31
31
 
32
32
  ```bash
33
+ bun run sync
33
34
  bun run build
34
35
  bun run typecheck
35
36
  ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wp-typia/create-workspace-template",
3
- "version": "0.13.0",
3
+ "version": "0.14.0",
4
4
  "description": "Official empty wp-typia workspace template package",
5
5
  "packageManager": "bun@1.3.11",
6
6
  "type": "module",
@@ -6,12 +6,13 @@
6
6
  "author": "{{author}}",
7
7
  "license": "GPL-2.0-or-later",
8
8
  "scripts": {
9
+ "sync": "tsx scripts/sync-project.ts",
9
10
  "sync-types": "tsx scripts/sync-types-to-block-json.ts",
10
11
  "sync-rest": "tsx scripts/sync-rest-contracts.ts",
11
- "build": "bun run sync-types --check && bun run sync-rest --check && node scripts/build-workspace.mjs build",
12
- "start": "bun run sync-types && bun run sync-rest && node scripts/build-workspace.mjs start",
12
+ "build": "bun run sync --check && node scripts/build-workspace.mjs build",
13
+ "start": "bun run sync && node scripts/build-workspace.mjs start",
13
14
  "dev": "bun run start",
14
- "typecheck": "bun run sync-types --check && bun run sync-rest --check && tsc --noEmit",
15
+ "typecheck": "bun run sync --check && tsc --noEmit",
15
16
  "lint:js": "wp-scripts lint-js",
16
17
  "lint:css": "wp-scripts lint-style",
17
18
  "lint": "bun run lint:js && bun run lint:css",
@@ -0,0 +1,103 @@
1
+ /* eslint-disable no-console */
2
+ import { spawnSync } from 'node:child_process';
3
+ import fs from 'node:fs';
4
+ import path from 'node:path';
5
+
6
+ interface SyncCliOptions {
7
+ check: boolean;
8
+ }
9
+
10
+ function parseCliOptions( argv: string[] ): SyncCliOptions {
11
+ const options: SyncCliOptions = {
12
+ check: false,
13
+ };
14
+
15
+ for ( const argument of argv ) {
16
+ if ( argument === '--check' ) {
17
+ options.check = true;
18
+ continue;
19
+ }
20
+
21
+ throw new Error( `Unknown sync flag: ${ argument }` );
22
+ }
23
+
24
+ return options;
25
+ }
26
+
27
+ function getSyncScriptEnv() {
28
+ const binaryDirectory = path.join( process.cwd(), 'node_modules', '.bin' );
29
+ const inheritedPath =
30
+ process.env.PATH ??
31
+ process.env.Path ??
32
+ Object.entries( process.env ).find(
33
+ ( [ key ] ) => key.toLowerCase() === 'path'
34
+ )?.[ 1 ] ??
35
+ '';
36
+ const nextPath = fs.existsSync( binaryDirectory )
37
+ ? `${ binaryDirectory }${ path.delimiter }${ inheritedPath }`
38
+ : inheritedPath;
39
+ const env: NodeJS.ProcessEnv = {
40
+ ...process.env,
41
+ };
42
+
43
+ for ( const key of Object.keys( env ) ) {
44
+ if ( key.toLowerCase() === 'path' ) {
45
+ delete env[ key ];
46
+ }
47
+ }
48
+
49
+ env.PATH = nextPath;
50
+
51
+ return env;
52
+ }
53
+
54
+ function runSyncScript( scriptPath: string, options: SyncCliOptions ) {
55
+ const args = [ scriptPath ];
56
+ if ( options.check ) {
57
+ args.push( '--check' );
58
+ }
59
+
60
+ const result = spawnSync( 'tsx', args, {
61
+ cwd: process.cwd(),
62
+ env: getSyncScriptEnv(),
63
+ shell: process.platform === 'win32',
64
+ stdio: 'inherit',
65
+ } );
66
+
67
+ if ( result.error ) {
68
+ if ( ( result.error as NodeJS.ErrnoException ).code === 'ENOENT' ) {
69
+ throw new Error(
70
+ 'Unable to resolve `tsx` for project sync. Install project dependencies or rerun the command through your package manager.'
71
+ );
72
+ }
73
+
74
+ throw result.error;
75
+ }
76
+
77
+ if ( result.status !== 0 ) {
78
+ throw new Error( `Sync script failed: ${ scriptPath }` );
79
+ }
80
+ }
81
+
82
+ async function main() {
83
+ const options = parseCliOptions( process.argv.slice( 2 ) );
84
+ const syncTypesScriptPath = path.join( 'scripts', 'sync-types-to-block-json.ts' );
85
+ const syncRestScriptPath = path.join( 'scripts', 'sync-rest-contracts.ts' );
86
+
87
+ runSyncScript( syncTypesScriptPath, options );
88
+
89
+ if ( fs.existsSync( path.resolve( process.cwd(), syncRestScriptPath ) ) ) {
90
+ runSyncScript( syncRestScriptPath, options );
91
+ }
92
+
93
+ console.log(
94
+ options.check
95
+ ? '✅ Generated project metadata and REST artifacts are already synchronized.'
96
+ : '✅ Generated project metadata and REST artifacts were synchronized.'
97
+ );
98
+ }
99
+
100
+ main().catch( ( error ) => {
101
+ console.error( '❌ Project sync failed:', error );
102
+ process.exit( 1 );
103
+ } );
@@ -2,6 +2,7 @@
2
2
  import path from 'node:path';
3
3
 
4
4
  import {
5
+ runSyncBlockMetadata,
5
6
  syncEndpointClient,
6
7
  syncRestOpenApi,
7
8
  syncTypeSchemas,
@@ -41,6 +42,34 @@ function isRestEnabledBlock(
41
42
  );
42
43
  }
43
44
 
45
+ async function assertTypeArtifactsCurrent( block: WorkspaceBlockConfig ) {
46
+ const report = await runSyncBlockMetadata(
47
+ {
48
+ blockJsonFile: path.join( 'src', 'blocks', block.slug, 'block.json' ),
49
+ jsonSchemaFile: path.join( 'src', 'blocks', block.slug, 'typia.schema.json' ),
50
+ manifestFile: path.join( 'src', 'blocks', block.slug, 'typia.manifest.json' ),
51
+ openApiFile: path.join( 'src', 'blocks', block.slug, 'typia.openapi.json' ),
52
+ sourceTypeName: block.attributeTypeName,
53
+ typesFile: block.typesFile,
54
+ },
55
+ {
56
+ check: true,
57
+ }
58
+ );
59
+
60
+ if ( report.failure?.code === 'stale-generated-artifact' ) {
61
+ throw new Error(
62
+ `${ block.slug }: ${ report.failure.message }\nRun \`sync\` or \`sync-types\` first to refresh type-derived artifacts before rerunning \`sync-rest\`.`
63
+ );
64
+ }
65
+
66
+ if ( report.failure ) {
67
+ throw new Error(
68
+ `${ block.slug }: type-derived artifact preflight failed before sync-rest.\n${ report.failure.message }`
69
+ );
70
+ }
71
+ }
72
+
44
73
  async function main() {
45
74
  const options = parseCliOptions( process.argv.slice( 2 ) );
46
75
  const restBlocks = BLOCKS.filter( isRestEnabledBlock );
@@ -55,6 +84,8 @@ async function main() {
55
84
  }
56
85
 
57
86
  for ( const block of restBlocks ) {
87
+ await assertTypeArtifactsCurrent( block );
88
+
58
89
  const contracts = block.restManifest.contracts;
59
90
 
60
91
  for ( const [ baseName, contract ] of Object.entries( contracts ) ) {
@@ -231,9 +231,13 @@ function getOptionalModuleEntries() {
231
231
  }
232
232
 
233
233
  module.exports = async () => {
234
- const { default: UnpluginTypia } = await import(
235
- '@typia/unplugin/webpack'
234
+ const { loadCompatibleTypiaWebpackPlugin } = await import(
235
+ '@wp-typia/block-runtime/blocks'
236
236
  );
237
+ const UnpluginTypia = await loadCompatibleTypiaWebpackPlugin( {
238
+ importTypiaWebpackPlugin: () => import( '@typia/unplugin/webpack' ),
239
+ projectRoot: process.cwd(),
240
+ } );
237
241
  const resolvedDefaultConfig =
238
242
  typeof defaultConfig === 'function'
239
243
  ? await defaultConfig()