tailwind-styled-v4 5.0.0 → 5.0.2

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.
Files changed (180) hide show
  1. package/CHANGELOG.md +398 -0
  2. package/LICENSE +21 -0
  3. package/README.md +532 -0
  4. package/dist/analyzer.d.mts +114 -0
  5. package/dist/analyzer.d.ts +114 -0
  6. package/dist/analyzer.js +6808 -0
  7. package/dist/analyzer.js.map +1 -0
  8. package/dist/analyzer.mjs +6798 -0
  9. package/dist/analyzer.mjs.map +1 -0
  10. package/dist/{animate.d.cts → animate.d.mts} +3 -30
  11. package/dist/animate.d.ts +3 -30
  12. package/dist/animate.js +7096 -352
  13. package/dist/animate.js.map +1 -1
  14. package/dist/animate.mjs +7482 -0
  15. package/dist/animate.mjs.map +1 -0
  16. package/dist/atomic.d.mts +18 -0
  17. package/dist/atomic.d.ts +18 -0
  18. package/dist/atomic.js +191 -0
  19. package/dist/atomic.js.map +1 -0
  20. package/dist/atomic.mjs +185 -0
  21. package/dist/atomic.mjs.map +1 -0
  22. package/dist/cli.d.mts +1 -0
  23. package/dist/cli.d.ts +1 -0
  24. package/dist/cli.js +45008 -0
  25. package/dist/cli.js.map +1 -0
  26. package/dist/cli.mjs +44980 -0
  27. package/dist/cli.mjs.map +1 -0
  28. package/dist/compiler.d.mts +1009 -0
  29. package/dist/compiler.d.ts +1009 -0
  30. package/dist/compiler.js +4937 -0
  31. package/dist/compiler.js.map +1 -0
  32. package/dist/compiler.mjs +4862 -0
  33. package/dist/compiler.mjs.map +1 -0
  34. package/dist/dashboard.d.mts +272 -0
  35. package/dist/dashboard.d.ts +272 -0
  36. package/dist/dashboard.js +249 -0
  37. package/dist/dashboard.js.map +1 -0
  38. package/dist/dashboard.mjs +239 -0
  39. package/dist/dashboard.mjs.map +1 -0
  40. package/dist/devtools.js +171 -158
  41. package/dist/devtools.js.map +1 -1
  42. package/dist/{devtools.cjs → devtools.mjs} +166 -167
  43. package/dist/devtools.mjs.map +1 -0
  44. package/dist/engine.d.mts +398 -0
  45. package/dist/engine.d.ts +398 -0
  46. package/dist/engine.js +19264 -0
  47. package/dist/engine.js.map +1 -0
  48. package/dist/engine.mjs +19227 -0
  49. package/dist/engine.mjs.map +1 -0
  50. package/dist/{index.d.cts → index.d.mts} +12 -5
  51. package/dist/index.d.ts +12 -5
  52. package/dist/index.js +7178 -27
  53. package/dist/index.js.map +1 -1
  54. package/dist/index.mjs +8408 -0
  55. package/dist/index.mjs.map +1 -0
  56. package/dist/liveTokenEngine-DYN3Zale.d.mts +34 -0
  57. package/dist/liveTokenEngine-DYN3Zale.d.ts +34 -0
  58. package/dist/{next.d.cts → next.d.mts} +2 -1
  59. package/dist/next.d.ts +2 -1
  60. package/dist/next.js +24027 -28
  61. package/dist/next.js.map +1 -1
  62. package/dist/next.mjs +24232 -0
  63. package/dist/next.mjs.map +1 -0
  64. package/dist/plugin.d.mts +90 -0
  65. package/dist/plugin.d.ts +90 -0
  66. package/dist/plugin.js +185 -0
  67. package/dist/plugin.js.map +1 -0
  68. package/dist/plugin.mjs +174 -0
  69. package/dist/plugin.mjs.map +1 -0
  70. package/dist/pluginRegistry.d.mts +83 -0
  71. package/dist/pluginRegistry.d.ts +83 -0
  72. package/dist/pluginRegistry.js +303 -0
  73. package/dist/pluginRegistry.js.map +1 -0
  74. package/dist/pluginRegistry.mjs +298 -0
  75. package/dist/pluginRegistry.mjs.map +1 -0
  76. package/dist/preset.js +9 -4
  77. package/dist/preset.js.map +1 -1
  78. package/dist/{preset.cjs → preset.mjs} +5 -14
  79. package/dist/preset.mjs.map +1 -0
  80. package/dist/rspack.d.mts +33 -0
  81. package/dist/rspack.d.ts +33 -0
  82. package/dist/rspack.js +66 -0
  83. package/dist/rspack.js.map +1 -0
  84. package/dist/rspack.mjs +55 -0
  85. package/dist/rspack.mjs.map +1 -0
  86. package/dist/runtime.d.mts +62 -0
  87. package/dist/runtime.d.ts +62 -0
  88. package/dist/runtime.js +455 -0
  89. package/dist/runtime.js.map +1 -0
  90. package/dist/runtime.mjs +436 -0
  91. package/dist/runtime.mjs.map +1 -0
  92. package/dist/runtimeCss.d.mts +65 -0
  93. package/dist/runtimeCss.d.ts +65 -0
  94. package/dist/{css.cjs → runtimeCss.js} +71 -4
  95. package/dist/runtimeCss.js.map +1 -0
  96. package/dist/{css.js → runtimeCss.mjs} +66 -5
  97. package/dist/runtimeCss.mjs.map +1 -0
  98. package/dist/scanner.d.mts +25 -0
  99. package/dist/scanner.d.ts +25 -0
  100. package/dist/scanner.js +5774 -0
  101. package/dist/scanner.js.map +1 -0
  102. package/dist/scanner.mjs +5760 -0
  103. package/dist/scanner.mjs.map +1 -0
  104. package/dist/shared.d.mts +85 -0
  105. package/dist/shared.d.ts +85 -0
  106. package/dist/shared.js +255 -0
  107. package/dist/shared.js.map +1 -0
  108. package/dist/shared.mjs +233 -0
  109. package/dist/shared.mjs.map +1 -0
  110. package/dist/storybookAddon.d.mts +108 -0
  111. package/dist/storybookAddon.d.ts +108 -0
  112. package/dist/storybookAddon.js +95 -0
  113. package/dist/storybookAddon.js.map +1 -0
  114. package/dist/storybookAddon.mjs +88 -0
  115. package/dist/storybookAddon.mjs.map +1 -0
  116. package/dist/svelte.d.mts +114 -0
  117. package/dist/svelte.d.ts +114 -0
  118. package/dist/svelte.js +67 -0
  119. package/dist/svelte.js.map +1 -0
  120. package/dist/svelte.mjs +59 -0
  121. package/dist/svelte.mjs.map +1 -0
  122. package/dist/testing.d.mts +185 -0
  123. package/dist/testing.d.ts +185 -0
  124. package/dist/testing.js +173 -0
  125. package/dist/testing.js.map +1 -0
  126. package/dist/testing.mjs +158 -0
  127. package/dist/testing.mjs.map +1 -0
  128. package/dist/theme.d.mts +188 -0
  129. package/dist/theme.d.ts +188 -0
  130. package/dist/theme.js +334 -0
  131. package/dist/theme.js.map +1 -0
  132. package/dist/theme.mjs +311 -0
  133. package/dist/theme.mjs.map +1 -0
  134. package/dist/tsconfig.tsbuildinfo +1 -0
  135. package/dist/types-DXr2PmGP.d.mts +31 -0
  136. package/dist/types-DXr2PmGP.d.ts +31 -0
  137. package/dist/vite.js +29611 -17
  138. package/dist/vite.js.map +1 -1
  139. package/dist/vite.mjs +29712 -0
  140. package/dist/vite.mjs.map +1 -0
  141. package/dist/vue.d.mts +89 -0
  142. package/dist/vue.d.ts +89 -0
  143. package/dist/vue.js +104 -0
  144. package/dist/vue.js.map +1 -0
  145. package/dist/vue.mjs +96 -0
  146. package/dist/vue.mjs.map +1 -0
  147. package/package.json +170 -64
  148. package/dist/animate.cjs +0 -771
  149. package/dist/animate.cjs.map +0 -1
  150. package/dist/chunk-VZEJV27B.js +0 -11
  151. package/dist/chunk-VZEJV27B.js.map +0 -1
  152. package/dist/chunk-Y5D3E72P.cjs +0 -13
  153. package/dist/chunk-Y5D3E72P.cjs.map +0 -1
  154. package/dist/css.cjs.map +0 -1
  155. package/dist/css.d.cts +0 -30
  156. package/dist/css.d.ts +0 -30
  157. package/dist/css.js.map +0 -1
  158. package/dist/devtools.cjs.map +0 -1
  159. package/dist/index.cjs +0 -1353
  160. package/dist/index.cjs.map +0 -1
  161. package/dist/next.cjs +0 -248
  162. package/dist/next.cjs.map +0 -1
  163. package/dist/preset.cjs.map +0 -1
  164. package/dist/turbopackLoader.cjs +0 -37
  165. package/dist/turbopackLoader.cjs.map +0 -1
  166. package/dist/turbopackLoader.d.cts +0 -12
  167. package/dist/turbopackLoader.d.ts +0 -12
  168. package/dist/turbopackLoader.js +0 -35
  169. package/dist/turbopackLoader.js.map +0 -1
  170. package/dist/vite.cjs +0 -138
  171. package/dist/vite.cjs.map +0 -1
  172. package/dist/webpackLoader.cjs +0 -51
  173. package/dist/webpackLoader.cjs.map +0 -1
  174. package/dist/webpackLoader.d.cts +0 -17
  175. package/dist/webpackLoader.d.ts +0 -17
  176. package/dist/webpackLoader.js +0 -49
  177. package/dist/webpackLoader.js.map +0 -1
  178. /package/dist/{devtools.d.cts → devtools.d.mts} +0 -0
  179. /package/dist/{preset.d.cts → preset.d.mts} +0 -0
  180. /package/dist/{vite.d.cts → vite.d.mts} +0 -0
@@ -0,0 +1,83 @@
1
+ interface PluginInfo {
2
+ name: string;
3
+ description: string;
4
+ version: string;
5
+ tags: string[];
6
+ official?: boolean;
7
+ docs?: string;
8
+ install?: string;
9
+ integrity?: string;
10
+ }
11
+ interface RegistryData {
12
+ version: string;
13
+ official: PluginInfo[];
14
+ community: PluginInfo[];
15
+ }
16
+ interface InstallResult {
17
+ plugin: string;
18
+ installed: boolean;
19
+ command: string;
20
+ exitCode: number;
21
+ }
22
+ type PluginRegistryErrorCode = "INVALID_PLUGIN_NAME" | "PLUGIN_NOT_FOUND" | "EXTERNAL_CONFIRMATION_REQUIRED" | "INSTALL_COMMAND_FAILED" | "INSTALL_FAILED" | "NETWORK_ERROR" | "REGISTRY_LOAD_FAILED";
23
+ interface PluginRegistryErrorPayload {
24
+ code: PluginRegistryErrorCode;
25
+ message: string;
26
+ context?: Record<string, unknown>;
27
+ }
28
+ declare class PluginRegistryError extends Error {
29
+ readonly code: PluginRegistryErrorCode;
30
+ readonly context?: Record<string, unknown>;
31
+ constructor(payload: PluginRegistryErrorPayload);
32
+ toObject(): PluginRegistryErrorPayload;
33
+ }
34
+ interface InstallOptions {
35
+ dryRun?: boolean;
36
+ npmBin?: string;
37
+ allowExternal?: boolean;
38
+ confirmExternal?: boolean;
39
+ }
40
+ interface RegistryOptions {
41
+ registryUrl?: string;
42
+ }
43
+ declare class PluginRegistry {
44
+ private readonly plugins;
45
+ private readonly registryVersion;
46
+ constructor(registryData?: RegistryData, options?: RegistryOptions);
47
+ static loadFromUrl(url: string): Promise<PluginRegistry>;
48
+ getVersion(): string;
49
+ search(query: string): PluginInfo[];
50
+ getAll(): PluginInfo[];
51
+ getByName(pluginName: string): PluginInfo | undefined;
52
+ install(pluginName: string, options?: InstallOptions): InstallResult;
53
+ uninstall(pluginName: string, options?: {
54
+ dryRun?: boolean;
55
+ npmBin?: string;
56
+ }): {
57
+ plugin: string;
58
+ uninstalled: boolean;
59
+ command: string;
60
+ exitCode: number;
61
+ };
62
+ verifyIntegrity(pluginName: string): {
63
+ ok: boolean;
64
+ reason?: string;
65
+ };
66
+ checkForUpdate(pluginName: string): {
67
+ hasUpdate: boolean;
68
+ current?: string;
69
+ latest?: string;
70
+ error?: string;
71
+ };
72
+ checkAllUpdates(): Array<{
73
+ name: string;
74
+ hasUpdate: boolean;
75
+ current?: string;
76
+ latest?: string;
77
+ error?: string;
78
+ }>;
79
+ }
80
+ declare function getRegistry(): PluginRegistry;
81
+ declare const registry: PluginRegistry;
82
+
83
+ export { type InstallOptions, type InstallResult, type PluginInfo, PluginRegistry, PluginRegistryError, type PluginRegistryErrorCode, type PluginRegistryErrorPayload, type RegistryOptions, getRegistry, registry };
@@ -0,0 +1,83 @@
1
+ interface PluginInfo {
2
+ name: string;
3
+ description: string;
4
+ version: string;
5
+ tags: string[];
6
+ official?: boolean;
7
+ docs?: string;
8
+ install?: string;
9
+ integrity?: string;
10
+ }
11
+ interface RegistryData {
12
+ version: string;
13
+ official: PluginInfo[];
14
+ community: PluginInfo[];
15
+ }
16
+ interface InstallResult {
17
+ plugin: string;
18
+ installed: boolean;
19
+ command: string;
20
+ exitCode: number;
21
+ }
22
+ type PluginRegistryErrorCode = "INVALID_PLUGIN_NAME" | "PLUGIN_NOT_FOUND" | "EXTERNAL_CONFIRMATION_REQUIRED" | "INSTALL_COMMAND_FAILED" | "INSTALL_FAILED" | "NETWORK_ERROR" | "REGISTRY_LOAD_FAILED";
23
+ interface PluginRegistryErrorPayload {
24
+ code: PluginRegistryErrorCode;
25
+ message: string;
26
+ context?: Record<string, unknown>;
27
+ }
28
+ declare class PluginRegistryError extends Error {
29
+ readonly code: PluginRegistryErrorCode;
30
+ readonly context?: Record<string, unknown>;
31
+ constructor(payload: PluginRegistryErrorPayload);
32
+ toObject(): PluginRegistryErrorPayload;
33
+ }
34
+ interface InstallOptions {
35
+ dryRun?: boolean;
36
+ npmBin?: string;
37
+ allowExternal?: boolean;
38
+ confirmExternal?: boolean;
39
+ }
40
+ interface RegistryOptions {
41
+ registryUrl?: string;
42
+ }
43
+ declare class PluginRegistry {
44
+ private readonly plugins;
45
+ private readonly registryVersion;
46
+ constructor(registryData?: RegistryData, options?: RegistryOptions);
47
+ static loadFromUrl(url: string): Promise<PluginRegistry>;
48
+ getVersion(): string;
49
+ search(query: string): PluginInfo[];
50
+ getAll(): PluginInfo[];
51
+ getByName(pluginName: string): PluginInfo | undefined;
52
+ install(pluginName: string, options?: InstallOptions): InstallResult;
53
+ uninstall(pluginName: string, options?: {
54
+ dryRun?: boolean;
55
+ npmBin?: string;
56
+ }): {
57
+ plugin: string;
58
+ uninstalled: boolean;
59
+ command: string;
60
+ exitCode: number;
61
+ };
62
+ verifyIntegrity(pluginName: string): {
63
+ ok: boolean;
64
+ reason?: string;
65
+ };
66
+ checkForUpdate(pluginName: string): {
67
+ hasUpdate: boolean;
68
+ current?: string;
69
+ latest?: string;
70
+ error?: string;
71
+ };
72
+ checkAllUpdates(): Array<{
73
+ name: string;
74
+ hasUpdate: boolean;
75
+ current?: string;
76
+ latest?: string;
77
+ error?: string;
78
+ }>;
79
+ }
80
+ declare function getRegistry(): PluginRegistry;
81
+ declare const registry: PluginRegistry;
82
+
83
+ export { type InstallOptions, type InstallResult, type PluginInfo, PluginRegistry, PluginRegistryError, type PluginRegistryErrorCode, type PluginRegistryErrorPayload, type RegistryOptions, getRegistry, registry };
@@ -0,0 +1,303 @@
1
+ 'use strict';
2
+
3
+ var child_process = require('child_process');
4
+ var crypto = require('crypto');
5
+ var fs = require('fs');
6
+ var path = require('path');
7
+
8
+ /* tailwind-styled-v4 v5.0.1 | MIT | https://github.com/dictionar32/tailwind-styled-v4 */
9
+ var __getOwnPropNames = Object.getOwnPropertyNames;
10
+ var __commonJS = (cb, mod) => function __require() {
11
+ return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
12
+ };
13
+
14
+ // packages/plugin-registry/registry.json
15
+ var require_registry = __commonJS({
16
+ "packages/plugin-registry/registry.json"(exports$1, module) {
17
+ module.exports = {
18
+ version: "5.0.0",
19
+ updatedAt: "2026-03-23",
20
+ official: [
21
+ {
22
+ name: "@tailwind-styled/plugin-animation",
23
+ description: "Animation presets and keyframes \u2014 enter/exit transitions, spring physics, scroll-triggered",
24
+ version: "5.0.0",
25
+ tags: ["animation", "motion", "transition", "keyframes"],
26
+ docs: "https://github.com/tailwind-styled/tailwind-styled-v5/tree/main/packages/animate",
27
+ install: "npm install @tailwind-styled/plugin-animation@5.0.0",
28
+ integrity: "sha256-abc123"
29
+ },
30
+ {
31
+ name: "@tailwind-styled/plugin-typography",
32
+ description: "Prose and typography utilities \u2014 headings, body, code blocks, with dark mode",
33
+ version: "5.0.0",
34
+ tags: ["typography", "prose", "markdown", "content"],
35
+ docs: "https://github.com/tailwind-styled/tailwind-styled-v5/tree/main/docs/plugins",
36
+ install: "npm install @tailwind-styled/plugin-typography@5.0.0",
37
+ integrity: "sha256-def456"
38
+ },
39
+ {
40
+ name: "@tailwind-styled/plugin-forms",
41
+ description: "Form input styling helpers \u2014 reset, validation states, custom checkboxes/radios",
42
+ version: "5.0.0",
43
+ tags: ["forms", "inputs", "validation", "checkbox", "radio"],
44
+ docs: "https://github.com/tailwind-styled/tailwind-styled-v5/tree/main/docs/plugins",
45
+ install: "npm install @tailwind-styled/plugin-forms@5.0.0",
46
+ integrity: "sha256-ghi789"
47
+ },
48
+ {
49
+ name: "@tailwind-styled/plugin-container-queries",
50
+ description: "Container query utilities \u2014 @container breakpoints for component-level responsiveness",
51
+ version: "5.0.0",
52
+ tags: ["container-queries", "responsive", "layout"],
53
+ docs: "https://github.com/tailwind-styled/tailwind-styled-v5/tree/main/docs/plugins",
54
+ install: "npm install @tailwind-styled/plugin-container-queries@5.0.0",
55
+ integrity: "sha256-jkl012"
56
+ }
57
+ ],
58
+ community: [
59
+ {
60
+ name: "tailwind-styled-animate",
61
+ description: "Community animation variants \u2014 bounce, pulse, wiggle, and more",
62
+ version: "0.1.0",
63
+ tags: ["animation", "community"],
64
+ author: "community",
65
+ install: "npm install tailwind-styled-animate"
66
+ },
67
+ {
68
+ name: "tailwind-styled-icons",
69
+ description: "SVG icon system integrated with tw() variant API",
70
+ version: "0.1.0",
71
+ tags: ["icons", "svg", "community"],
72
+ author: "community",
73
+ install: "npm install tailwind-styled-icons"
74
+ }
75
+ ]
76
+ };
77
+ }
78
+ });
79
+ var PLUGIN_NAME_REGEX = /^(@[a-z0-9-]+\/)?[a-z0-9-]+(@[0-9]+\.[0-9]+\.[0-9]+)?$/;
80
+ var PluginRegistryError = class extends Error {
81
+ constructor(payload) {
82
+ super(payload.message);
83
+ this.name = "PluginRegistryError";
84
+ this.code = payload.code;
85
+ this.context = payload.context;
86
+ }
87
+ toObject() {
88
+ return {
89
+ code: this.code,
90
+ message: this.message,
91
+ context: this.context
92
+ };
93
+ }
94
+ };
95
+ var PluginRegistry = class _PluginRegistry {
96
+ constructor(registryData, options = {}) {
97
+ if (options.registryUrl) {
98
+ this.plugins = [];
99
+ this.registryVersion = "0.0.0";
100
+ } else {
101
+ const data = registryData;
102
+ const version = data?.version ?? "4.2.0";
103
+ const official = (data?.official ?? []).map((item) => ({
104
+ name: item.name,
105
+ description: item.description,
106
+ version: item.version,
107
+ tags: [...item.tags],
108
+ official: true,
109
+ docs: item.docs,
110
+ install: item.install,
111
+ integrity: item.integrity
112
+ }));
113
+ const community = (data?.community ?? []).map((item) => ({
114
+ name: item.name,
115
+ description: item.description,
116
+ version: item.version,
117
+ tags: [...item.tags],
118
+ official: false
119
+ }));
120
+ this.plugins = [...official, ...community];
121
+ this.registryVersion = version;
122
+ }
123
+ }
124
+ static async loadFromUrl(url) {
125
+ try {
126
+ const response = await fetch(url);
127
+ if (!response.ok) {
128
+ throw new PluginRegistryError({
129
+ code: "NETWORK_ERROR",
130
+ message: `Failed to fetch registry: ${response.status} ${response.statusText}`,
131
+ context: { url, status: response.status }
132
+ });
133
+ }
134
+ const data = await response.json();
135
+ return new _PluginRegistry(data, { registryUrl: url });
136
+ } catch (error) {
137
+ if (error instanceof PluginRegistryError) throw error;
138
+ throw new PluginRegistryError({
139
+ code: "NETWORK_ERROR",
140
+ message: `Failed to load registry: ${error instanceof Error ? error.message : String(error)}`,
141
+ context: { url }
142
+ });
143
+ }
144
+ }
145
+ getVersion() {
146
+ return this.registryVersion;
147
+ }
148
+ search(query) {
149
+ const q = query.trim().toLowerCase();
150
+ if (!q) return [...this.plugins];
151
+ return this.plugins.filter((plugin) => {
152
+ return plugin.name.toLowerCase().includes(q) || plugin.description.toLowerCase().includes(q) || plugin.tags.some((tag) => tag.toLowerCase().includes(q));
153
+ });
154
+ }
155
+ getAll() {
156
+ return [...this.plugins];
157
+ }
158
+ getByName(pluginName) {
159
+ const nameWithoutVersion = pluginName.split("@").slice(0, 2).join("@");
160
+ return this.plugins.find((plugin) => plugin.name === nameWithoutVersion);
161
+ }
162
+ install(pluginName, options = {}) {
163
+ const npmBin = options.npmBin ?? process.env.TW_PLUGIN_NPM_BIN ?? "npm";
164
+ if (!PLUGIN_NAME_REGEX.test(pluginName)) {
165
+ throw new PluginRegistryError({
166
+ code: "INVALID_PLUGIN_NAME",
167
+ message: `Nama plugin tidak valid: '${pluginName}'.`,
168
+ context: {
169
+ pluginName,
170
+ expectedPattern: String(PLUGIN_NAME_REGEX)
171
+ }
172
+ });
173
+ }
174
+ const knownPlugin = this.getByName(pluginName);
175
+ const isExternal = !knownPlugin;
176
+ if (isExternal && !options.allowExternal) {
177
+ throw new PluginRegistryError({
178
+ code: "PLUGIN_NOT_FOUND",
179
+ message: `Plugin '${pluginName}' tidak ditemukan di registry. Coba cari dengan 'tw-plugin search <keyword>'.`,
180
+ context: {
181
+ pluginName,
182
+ allowExternal: false
183
+ }
184
+ });
185
+ }
186
+ if (isExternal && options.allowExternal && !options.confirmExternal) {
187
+ throw new PluginRegistryError({
188
+ code: "EXTERNAL_CONFIRMATION_REQUIRED",
189
+ message: `Plugin eksternal '${pluginName}' butuh konfirmasi. Jalankan ulang dengan --allow-external --yes.`,
190
+ context: {
191
+ pluginName,
192
+ allowExternal: true
193
+ }
194
+ });
195
+ }
196
+ const command = `${npmBin} install ${pluginName}`;
197
+ if (options.dryRun) {
198
+ return { plugin: pluginName, installed: true, command, exitCode: 0 };
199
+ }
200
+ const child = child_process.spawnSync(npmBin, ["install", pluginName], { stdio: "inherit" });
201
+ if (child.error) {
202
+ throw new PluginRegistryError({
203
+ code: "INSTALL_COMMAND_FAILED",
204
+ message: `Gagal menjalankan perintah install: ${command}`,
205
+ context: {
206
+ pluginName,
207
+ command,
208
+ reason: child.error.message
209
+ }
210
+ });
211
+ }
212
+ if (child.status !== 0) {
213
+ throw new PluginRegistryError({
214
+ code: "INSTALL_FAILED",
215
+ message: `Install gagal (${child.status ?? 1}): ${command}`,
216
+ context: {
217
+ pluginName,
218
+ command,
219
+ exitCode: child.status ?? 1
220
+ }
221
+ });
222
+ }
223
+ return {
224
+ plugin: pluginName,
225
+ installed: true,
226
+ command,
227
+ exitCode: 0
228
+ };
229
+ }
230
+ uninstall(pluginName, options = {}) {
231
+ const npmBin = options.npmBin ?? process.env.TW_PLUGIN_NPM_BIN ?? "npm";
232
+ const command = `${npmBin} uninstall ${pluginName}`;
233
+ if (options.dryRun) {
234
+ return { plugin: pluginName, uninstalled: true, command, exitCode: 0 };
235
+ }
236
+ const child = child_process.spawnSync(npmBin, ["uninstall", pluginName], { stdio: "inherit" });
237
+ if (child.status !== 0 && child.status !== null) {
238
+ throw new PluginRegistryError({
239
+ code: "INSTALL_FAILED",
240
+ message: `Uninstall gagal (${child.status}): ${command}`,
241
+ context: { pluginName, command, exitCode: child.status }
242
+ });
243
+ }
244
+ return {
245
+ plugin: pluginName,
246
+ uninstalled: true,
247
+ command,
248
+ exitCode: child.status ?? 0
249
+ };
250
+ }
251
+ verifyIntegrity(pluginName) {
252
+ const plugin = this.getByName(pluginName);
253
+ if (!plugin) return { ok: false, reason: `Plugin '${pluginName}' not in registry` };
254
+ if (!plugin.integrity) {
255
+ return { ok: true, reason: "no checksum registered (skip)" };
256
+ }
257
+ try {
258
+ const pkgPath = path.join(process.cwd(), "node_modules", pluginName, "package.json");
259
+ if (!fs.existsSync(pkgPath)) return { ok: false, reason: "plugin not installed" };
260
+ const content = fs.readFileSync(pkgPath, "utf8");
261
+ const hash = "sha256-" + crypto.createHash("sha256").update(content).digest("base64");
262
+ return hash === plugin.integrity ? { ok: true } : { ok: false, reason: `Integrity mismatch: expected ${plugin.integrity}` };
263
+ } catch (e) {
264
+ return { ok: false, reason: `Integrity check failed: ${e.message}` };
265
+ }
266
+ }
267
+ checkForUpdate(pluginName) {
268
+ const plugin = this.getByName(pluginName);
269
+ if (!plugin) return { hasUpdate: false, error: `Plugin '${pluginName}' not in registry` };
270
+ try {
271
+ const pkgPath = path.join(process.cwd(), "node_modules", pluginName, "package.json");
272
+ if (!fs.existsSync(pkgPath)) return { hasUpdate: false, error: "plugin not installed" };
273
+ const current = JSON.parse(fs.readFileSync(pkgPath, "utf8")).version ?? "0.0.0";
274
+ const latest = plugin.version;
275
+ const parseV = (v) => v.replace(/[^0-9.]/g, "").split(".").map(Number);
276
+ const [ca, cb, cc] = parseV(current);
277
+ const [la, lb, lc] = parseV(latest);
278
+ const hasUpdate = la > ca || la === ca && lb > cb || la === ca && lb === cb && lc > cc;
279
+ return { hasUpdate, current, latest };
280
+ } catch (e) {
281
+ return { hasUpdate: false, error: `Update check failed: ${e.message}` };
282
+ }
283
+ }
284
+ checkAllUpdates() {
285
+ return this.plugins.map((p) => ({ name: p.name, ...this.checkForUpdate(p.name) }));
286
+ }
287
+ };
288
+ var defaultRegistry = null;
289
+ function getRegistry() {
290
+ if (!defaultRegistry) {
291
+ const registryData = require_registry();
292
+ defaultRegistry = new PluginRegistry(registryData);
293
+ }
294
+ return defaultRegistry;
295
+ }
296
+ var registry = getRegistry();
297
+
298
+ exports.PluginRegistry = PluginRegistry;
299
+ exports.PluginRegistryError = PluginRegistryError;
300
+ exports.getRegistry = getRegistry;
301
+ exports.registry = registry;
302
+ //# sourceMappingURL=pluginRegistry.js.map
303
+ //# sourceMappingURL=pluginRegistry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../packages/plugin-registry/registry.json","../packages/plugin-registry/src/index.ts"],"names":["exports","spawnSync","join","existsSync","readFileSync","createHash"],"mappings":"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","file":"pluginRegistry.js","sourcesContent":["{\n \"version\": \"5.0.0\",\n \"updatedAt\": \"2026-03-23\",\n \"official\": [\n {\n \"name\": \"@tailwind-styled/plugin-animation\",\n \"description\": \"Animation presets and keyframes — enter/exit transitions, spring physics, scroll-triggered\",\n \"version\": \"5.0.0\",\n \"tags\": [\"animation\", \"motion\", \"transition\", \"keyframes\"],\n \"docs\": \"https://github.com/tailwind-styled/tailwind-styled-v5/tree/main/packages/animate\",\n \"install\": \"npm install @tailwind-styled/plugin-animation@5.0.0\",\n \"integrity\": \"sha256-abc123\"\n },\n {\n \"name\": \"@tailwind-styled/plugin-typography\",\n \"description\": \"Prose and typography utilities — headings, body, code blocks, with dark mode\",\n \"version\": \"5.0.0\",\n \"tags\": [\"typography\", \"prose\", \"markdown\", \"content\"],\n \"docs\": \"https://github.com/tailwind-styled/tailwind-styled-v5/tree/main/docs/plugins\",\n \"install\": \"npm install @tailwind-styled/plugin-typography@5.0.0\",\n \"integrity\": \"sha256-def456\"\n },\n {\n \"name\": \"@tailwind-styled/plugin-forms\",\n \"description\": \"Form input styling helpers — reset, validation states, custom checkboxes/radios\",\n \"version\": \"5.0.0\",\n \"tags\": [\"forms\", \"inputs\", \"validation\", \"checkbox\", \"radio\"],\n \"docs\": \"https://github.com/tailwind-styled/tailwind-styled-v5/tree/main/docs/plugins\",\n \"install\": \"npm install @tailwind-styled/plugin-forms@5.0.0\",\n \"integrity\": \"sha256-ghi789\"\n },\n {\n \"name\": \"@tailwind-styled/plugin-container-queries\",\n \"description\": \"Container query utilities — @container breakpoints for component-level responsiveness\",\n \"version\": \"5.0.0\",\n \"tags\": [\"container-queries\", \"responsive\", \"layout\"],\n \"docs\": \"https://github.com/tailwind-styled/tailwind-styled-v5/tree/main/docs/plugins\",\n \"install\": \"npm install @tailwind-styled/plugin-container-queries@5.0.0\",\n \"integrity\": \"sha256-jkl012\"\n }\n ],\n \"community\": [\n {\n \"name\": \"tailwind-styled-animate\",\n \"description\": \"Community animation variants — bounce, pulse, wiggle, and more\",\n \"version\": \"0.1.0\",\n \"tags\": [\"animation\", \"community\"],\n \"author\": \"community\",\n \"install\": \"npm install tailwind-styled-animate\"\n },\n {\n \"name\": \"tailwind-styled-icons\",\n \"description\": \"SVG icon system integrated with tw() variant API\",\n \"version\": \"0.1.0\",\n \"tags\": [\"icons\", \"svg\", \"community\"],\n \"author\": \"community\",\n \"install\": \"npm install tailwind-styled-icons\"\n }\n ]\n}\n","import { spawnSync } from \"node:child_process\"\nimport { createHash } from \"node:crypto\"\nimport { existsSync, readFileSync } from \"node:fs\"\nimport { join } from \"node:path\"\n\nconst PLUGIN_NAME_REGEX = /^(@[a-z0-9-]+\\/)?[a-z0-9-]+(@[0-9]+\\.[0-9]+\\.[0-9]+)?$/\n\nexport interface PluginInfo {\n name: string\n description: string\n version: string\n tags: string[]\n official?: boolean\n docs?: string\n install?: string\n integrity?: string\n}\n\ninterface RegistryData {\n version: string\n official: PluginInfo[]\n community: PluginInfo[]\n}\n\nexport interface InstallResult {\n plugin: string\n installed: boolean\n command: string\n exitCode: number\n}\n\nexport type PluginRegistryErrorCode =\n | \"INVALID_PLUGIN_NAME\"\n | \"PLUGIN_NOT_FOUND\"\n | \"EXTERNAL_CONFIRMATION_REQUIRED\"\n | \"INSTALL_COMMAND_FAILED\"\n | \"INSTALL_FAILED\"\n | \"NETWORK_ERROR\"\n | \"REGISTRY_LOAD_FAILED\"\n\nexport interface PluginRegistryErrorPayload {\n code: PluginRegistryErrorCode\n message: string\n context?: Record<string, unknown>\n}\n\nexport class PluginRegistryError extends Error {\n readonly code: PluginRegistryErrorCode\n readonly context?: Record<string, unknown>\n\n constructor(payload: PluginRegistryErrorPayload) {\n super(payload.message)\n this.name = \"PluginRegistryError\"\n this.code = payload.code\n this.context = payload.context\n }\n\n toObject(): PluginRegistryErrorPayload {\n return {\n code: this.code,\n message: this.message,\n context: this.context,\n }\n }\n}\n\nexport interface InstallOptions {\n dryRun?: boolean\n npmBin?: string\n allowExternal?: boolean\n confirmExternal?: boolean\n}\n\nexport interface RegistryOptions {\n registryUrl?: string\n}\n\nexport class PluginRegistry {\n private readonly plugins: PluginInfo[]\n private readonly registryVersion: string\n\n constructor(registryData?: RegistryData, options: RegistryOptions = {}) {\n if (options.registryUrl) {\n this.plugins = []\n this.registryVersion = \"0.0.0\"\n } else {\n const data = registryData\n const version = data?.version ?? \"4.2.0\"\n const official = (data?.official ?? []).map((item) => ({\n name: item.name,\n description: item.description,\n version: item.version,\n tags: [...item.tags],\n official: true,\n docs: item.docs,\n install: item.install,\n integrity: item.integrity,\n }))\n const community = (data?.community ?? []).map((item) => ({\n name: item.name,\n description: item.description,\n version: item.version,\n tags: [...item.tags],\n official: false,\n }))\n this.plugins = [...official, ...community]\n this.registryVersion = version\n }\n }\n\n static async loadFromUrl(url: string): Promise<PluginRegistry> {\n try {\n const response = await fetch(url)\n if (!response.ok) {\n throw new PluginRegistryError({\n code: \"NETWORK_ERROR\",\n message: `Failed to fetch registry: ${response.status} ${response.statusText}`,\n context: { url, status: response.status },\n })\n }\n const data = (await response.json()) as RegistryData\n return new PluginRegistry(data, { registryUrl: url })\n } catch (error) {\n if (error instanceof PluginRegistryError) throw error\n throw new PluginRegistryError({\n code: \"NETWORK_ERROR\",\n message: `Failed to load registry: ${error instanceof Error ? error.message : String(error)}`,\n context: { url },\n })\n }\n }\n\n getVersion(): string {\n return this.registryVersion\n }\n\n search(query: string): PluginInfo[] {\n const q = query.trim().toLowerCase()\n if (!q) return [...this.plugins]\n\n return this.plugins.filter((plugin) => {\n return (\n plugin.name.toLowerCase().includes(q) ||\n plugin.description.toLowerCase().includes(q) ||\n plugin.tags.some((tag) => tag.toLowerCase().includes(q))\n )\n })\n }\n\n getAll(): PluginInfo[] {\n return [...this.plugins]\n }\n\n getByName(pluginName: string): PluginInfo | undefined {\n const nameWithoutVersion = pluginName.split(\"@\").slice(0, 2).join(\"@\")\n return this.plugins.find((plugin) => plugin.name === nameWithoutVersion)\n }\n\n install(pluginName: string, options: InstallOptions = {}): InstallResult {\n const npmBin = options.npmBin ?? process.env.TW_PLUGIN_NPM_BIN ?? \"npm\"\n\n if (!PLUGIN_NAME_REGEX.test(pluginName)) {\n throw new PluginRegistryError({\n code: \"INVALID_PLUGIN_NAME\",\n message: `Nama plugin tidak valid: '${pluginName}'.`,\n context: {\n pluginName,\n expectedPattern: String(PLUGIN_NAME_REGEX),\n },\n })\n }\n\n const knownPlugin = this.getByName(pluginName)\n const isExternal = !knownPlugin\n\n if (isExternal && !options.allowExternal) {\n throw new PluginRegistryError({\n code: \"PLUGIN_NOT_FOUND\",\n message: `Plugin '${pluginName}' tidak ditemukan di registry. Coba cari dengan 'tw-plugin search <keyword>'.`,\n context: {\n pluginName,\n allowExternal: false,\n },\n })\n }\n\n if (isExternal && options.allowExternal && !options.confirmExternal) {\n throw new PluginRegistryError({\n code: \"EXTERNAL_CONFIRMATION_REQUIRED\",\n message: `Plugin eksternal '${pluginName}' butuh konfirmasi. Jalankan ulang dengan --allow-external --yes.`,\n context: {\n pluginName,\n allowExternal: true,\n },\n })\n }\n\n const command = `${npmBin} install ${pluginName}`\n if (options.dryRun) {\n return { plugin: pluginName, installed: true, command, exitCode: 0 }\n }\n\n const child = spawnSync(npmBin, [\"install\", pluginName], { stdio: \"inherit\" })\n if (child.error) {\n throw new PluginRegistryError({\n code: \"INSTALL_COMMAND_FAILED\",\n message: `Gagal menjalankan perintah install: ${command}`,\n context: {\n pluginName,\n command,\n reason: child.error.message,\n },\n })\n }\n\n if (child.status !== 0) {\n throw new PluginRegistryError({\n code: \"INSTALL_FAILED\",\n message: `Install gagal (${child.status ?? 1}): ${command}`,\n context: {\n pluginName,\n command,\n exitCode: child.status ?? 1,\n },\n })\n }\n\n return {\n plugin: pluginName,\n installed: true,\n command,\n exitCode: 0,\n }\n }\n\n uninstall(\n pluginName: string,\n options: { dryRun?: boolean; npmBin?: string } = {}\n ): {\n plugin: string\n uninstalled: boolean\n command: string\n exitCode: number\n } {\n const npmBin = options.npmBin ?? process.env.TW_PLUGIN_NPM_BIN ?? \"npm\"\n const command = `${npmBin} uninstall ${pluginName}`\n\n if (options.dryRun) {\n return { plugin: pluginName, uninstalled: true, command, exitCode: 0 }\n }\n\n const child = spawnSync(npmBin, [\"uninstall\", pluginName], { stdio: \"inherit\" })\n if (child.status !== 0 && child.status !== null) {\n throw new PluginRegistryError({\n code: \"INSTALL_FAILED\",\n message: `Uninstall gagal (${child.status}): ${command}`,\n context: { pluginName, command, exitCode: child.status },\n })\n }\n\n return {\n plugin: pluginName,\n uninstalled: true,\n command,\n exitCode: child.status ?? 0,\n }\n }\n\n verifyIntegrity(pluginName: string): { ok: boolean; reason?: string } {\n const plugin = this.getByName(pluginName)\n if (!plugin) return { ok: false, reason: `Plugin '${pluginName}' not in registry` }\n if (!plugin.integrity) {\n return { ok: true, reason: \"no checksum registered (skip)\" }\n }\n try {\n const pkgPath = join(process.cwd(), \"node_modules\", pluginName, \"package.json\")\n if (!existsSync(pkgPath)) return { ok: false, reason: \"plugin not installed\" }\n const content = readFileSync(pkgPath, \"utf8\")\n const hash = \"sha256-\" + createHash(\"sha256\").update(content).digest(\"base64\")\n return hash === plugin.integrity\n ? { ok: true }\n : { ok: false, reason: `Integrity mismatch: expected ${plugin.integrity}` }\n } catch (e: any) {\n return { ok: false, reason: `Integrity check failed: ${e.message}` }\n }\n }\n\n checkForUpdate(pluginName: string): {\n hasUpdate: boolean\n current?: string\n latest?: string\n error?: string\n } {\n const plugin = this.getByName(pluginName)\n if (!plugin) return { hasUpdate: false, error: `Plugin '${pluginName}' not in registry` }\n try {\n const pkgPath = join(process.cwd(), \"node_modules\", pluginName, \"package.json\")\n if (!existsSync(pkgPath)) return { hasUpdate: false, error: \"plugin not installed\" }\n const current = JSON.parse(readFileSync(pkgPath, \"utf8\")).version ?? \"0.0.0\"\n const latest = plugin.version\n const parseV = (v: string) =>\n v\n .replace(/[^0-9.]/g, \"\")\n .split(\".\")\n .map(Number)\n const [ca, cb, cc] = parseV(current)\n const [la, lb, lc] = parseV(latest)\n const hasUpdate = la > ca || (la === ca && lb > cb) || (la === ca && lb === cb && lc > cc)\n return { hasUpdate, current, latest }\n } catch (e: any) {\n return { hasUpdate: false, error: `Update check failed: ${e.message}` }\n }\n }\n\n checkAllUpdates(): Array<{\n name: string\n hasUpdate: boolean\n current?: string\n latest?: string\n error?: string\n }> {\n return this.plugins.map((p) => ({ name: p.name, ...this.checkForUpdate(p.name) }))\n }\n}\n\nlet defaultRegistry: PluginRegistry | null = null\n\nexport function getRegistry(): PluginRegistry {\n if (!defaultRegistry) {\n const registryData = require(\"../registry.json\") as RegistryData\n defaultRegistry = new PluginRegistry(registryData)\n }\n return defaultRegistry\n}\n\nexport const registry = getRegistry()\n"]}