Repository navigation
Expand file tree
/
Copy pathimplementation.ts
More file actions
222 lines (208 loc) · 6.37 KB
/
Copy pathimplementation.ts
File metadata and controls
222 lines (208 loc) · 6.37 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
/**
* wordpress/private-apis – the utilities to enable private cross-package
* exports of private APIs.
*
* This "implementation.ts" file is needed for the sake of the unit tests. It
* exports more than the public API of the package to aid in testing.
*/
/**
* The list of core modules allowed to opt-in to the private APIs.
*/
const CORE_MODULES_USING_PRIVATE_APIS = [
'@wordpress/admin-ui',
'@wordpress/api-fetch',
'@wordpress/block-directory',
'@wordpress/block-editor',
'@wordpress/block-library',
'@wordpress/blocks',
'@wordpress/boot',
'@wordpress/commands',
'@wordpress/compose',
'@wordpress/connectors',
'@wordpress/workflows',
'@wordpress/components',
'@wordpress/core-actions',
'@wordpress/core-commands',
'@wordpress/core-data',
'@wordpress/core-fields',
'@wordpress/customize-widgets',
'@wordpress/data',
'@wordpress/edit-post',
'@wordpress/edit-site',
'@wordpress/edit-widgets',
'@wordpress/editor',
'@wordpress/font-list-route',
'@wordpress/format-library',
'@wordpress/notices',
'@wordpress/patterns',
'@wordpress/preferences',
'@wordpress/rich-text',
'@wordpress/route',
'@wordpress/router',
'@wordpress/routes',
'@wordpress/storybook',
'@wordpress/theme',
// Do not remove: older `@wordpress/dataviews` versions published to npm
// call the opt-in at module load, so a plugin bundling one of those
// copies throws at load time if this entry is missing.
'@wordpress/dataviews',
// Do not remove: older `@wordpress/sync` versions published to npm call
// the opt-in at module load, so a plugin bundling one of those copies
// throws at load time if this entry is missing.
'@wordpress/sync',
'@wordpress/fields',
'@wordpress/lazy-editor',
'@wordpress/media-editor',
'@wordpress/media-utils',
'@wordpress/upload-media',
'@wordpress/global-styles-engine',
'@wordpress/global-styles-ui',
'@wordpress/ui',
'@wordpress/views',
'@wordpress/widget-dashboard',
];
/*
* Warning for theme and plugin developers.
*
* The use of private developer APIs is intended for use by WordPress Core
* and the Gutenberg plugin exclusively.
*
* Dangerously opting in to using these APIs is NOT RECOMMENDED. Furthermore,
* the WordPress Core philosophy to strive to maintain backward compatibility
* for third-party developers DOES NOT APPLY to private APIs.
*
* THE CONSENT STRING FOR OPTING IN TO THESE APIS MAY CHANGE AT ANY TIME AND
* WITHOUT NOTICE. THIS CHANGE WILL BREAK EXISTING THIRD-PARTY CODE. SUCH A
* CHANGE MAY OCCUR IN EITHER A MAJOR OR MINOR RELEASE.
*/
const requiredConsent =
'I acknowledge private features are not for use in themes or plugins and doing so will break in the next version of WordPress.';
/**
* Called by a `@wordpress` package wishing to opt-in to accessing or exposing
* private private APIs.
*
* @param consent The consent string.
* @param moduleName The name of the module that is opting in.
* @return An object containing the lock and unlock functions.
*/
export const __dangerousOptInToUnstableAPIsOnlyForCoreModules = (
consent: string,
moduleName: string
) => {
if ( ! CORE_MODULES_USING_PRIVATE_APIS.includes( moduleName ) ) {
throw new Error(
`You tried to opt-in to unstable APIs as module "${ moduleName }". ` +
'This feature is only for JavaScript modules shipped with WordPress core. ' +
'Please do not use it in plugins and themes as the unstable APIs will be removed ' +
'without a warning. If you ignore this error and depend on unstable features, ' +
'your product will inevitably break on one of the next WordPress releases.'
);
}
if ( consent !== requiredConsent ) {
throw new Error(
`You tried to opt-in to unstable APIs without confirming you know the consequences. ` +
'This feature is only for JavaScript modules shipped with WordPress core. ' +
'Please do not use it in plugins and themes as the unstable APIs will removed ' +
'without a warning. If you ignore this error and depend on unstable features, ' +
'your product will inevitably break on the next WordPress release.'
);
}
return {
lock,
unlock,
};
};
/**
* Binds private data to an object.
* It does not alter the passed object in any way, only
* registers it in an internal map of private data.
*
* The private data can't be accessed by any other means
* than the `unlock` function.
*
* @example
* ```js
* const object = {};
* const privateData = { a: 1 };
* lock( object, privateData );
*
* object
* // {}
*
* unlock( object );
* // { a: 1 }
* ```
*
* @param object The object to bind the private data to.
* @param privateData The private data to bind to the object.
*/
function lock( object: unknown, privateData: unknown ) {
if ( ! object ) {
throw new Error( 'Cannot lock an undefined object.' );
}
const _object = object as Record< symbol, WeakKey >;
if ( ! ( __private in _object ) ) {
_object[ __private ] = {};
}
lockedData.set( _object[ __private ], privateData );
}
/**
* Unlocks the private data bound to an object.
*
* It does not alter the passed object in any way, only
* returns the private data paired with it using the `lock()`
* function.
*
* @example
* ```js
* const object = {};
* const privateData = { a: 1 };
* lock( object, privateData );
*
* object
* // {}
*
* unlock( object );
* // { a: 1 }
* ```
*
* @param object The object to unlock the private data from.
* @return The private data bound to the object.
*/
function unlock< T = any >( object: unknown ): T {
if ( ! object ) {
throw new Error( 'Cannot unlock an undefined object.' );
}
const _object = object as Record< symbol, WeakKey >;
if ( ! ( __private in _object ) ) {
throw new Error(
'Cannot unlock an object that was not locked before. '
);
}
return lockedData.get( _object[ __private ] );
}
const lockedData = new WeakMap();
/**
* Used by lock() and unlock() to uniquely identify the private data
* related to a containing object.
*/
const __private = Symbol( 'Private API ID' );
// Unit tests utilities:
/**
* Private function to allow the unit tests to allow
* a mock module to access the private APIs.
*
* @param name The name of the module.
*/
export function allowCoreModule( name: string ) {
CORE_MODULES_USING_PRIVATE_APIS.push( name );
}
/**
* Private function to allow the unit tests to set
* a custom list of allowed modules.
*/
export function resetAllowedCoreModules() {
while ( CORE_MODULES_USING_PRIVATE_APIS.length ) {
CORE_MODULES_USING_PRIVATE_APIS.pop();
}
}