@wp-typia/project-tools 0.21.0 → 0.22.1

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 (34) hide show
  1. package/dist/runtime/ai-feature-capability.js +2 -33
  2. package/dist/runtime/built-in-block-artifact-types.js +11 -0
  3. package/dist/runtime/built-in-block-code-artifacts.js +5 -1
  4. package/dist/runtime/built-in-block-code-templates/interactivity.d.ts +4 -3
  5. package/dist/runtime/built-in-block-code-templates/interactivity.js +259 -100
  6. package/dist/runtime/built-in-block-code-templates.d.ts +1 -1
  7. package/dist/runtime/built-in-block-code-templates.js +1 -1
  8. package/dist/runtime/cli-add-shared.d.ts +4 -3
  9. package/dist/runtime/cli-add-shared.js +5 -2
  10. package/dist/runtime/cli-add-workspace-ability.js +3 -4
  11. package/dist/runtime/cli-add-workspace-admin-view-scaffold.d.ts +9 -0
  12. package/dist/runtime/cli-add-workspace-admin-view-scaffold.js +257 -0
  13. package/dist/runtime/cli-add-workspace-admin-view-source.d.ts +5 -0
  14. package/dist/runtime/cli-add-workspace-admin-view-source.js +86 -0
  15. package/dist/runtime/cli-add-workspace-admin-view-templates.d.ts +23 -0
  16. package/dist/runtime/cli-add-workspace-admin-view-templates.js +991 -0
  17. package/dist/runtime/cli-add-workspace-admin-view-types.d.ts +29 -0
  18. package/dist/runtime/cli-add-workspace-admin-view-types.js +29 -0
  19. package/dist/runtime/cli-add-workspace-admin-view.d.ts +1 -14
  20. package/dist/runtime/cli-add-workspace-admin-view.js +23 -860
  21. package/dist/runtime/cli-doctor-workspace.js +5 -4
  22. package/dist/runtime/cli-help.js +5 -2
  23. package/dist/runtime/external-layer-selection.d.ts +8 -2
  24. package/dist/runtime/external-layer-selection.js +3 -4
  25. package/dist/runtime/package-versions.d.ts +28 -0
  26. package/dist/runtime/package-versions.js +79 -36
  27. package/dist/runtime/scaffold-compatibility.d.ts +2 -2
  28. package/dist/runtime/scaffold-compatibility.js +22 -48
  29. package/dist/runtime/string-case.d.ts +7 -0
  30. package/dist/runtime/string-case.js +21 -11
  31. package/dist/runtime/version-floor.d.ts +26 -0
  32. package/dist/runtime/version-floor.js +56 -0
  33. package/dist/runtime/workspace-inventory.d.ts +2 -1
  34. package/package.json +3 -2
@@ -0,0 +1,257 @@
1
+ import fs from 'node:fs';
2
+ import { promises as fsp } from 'node:fs';
3
+ import path from 'node:path';
4
+ import { appendWorkspaceInventoryEntries, readWorkspaceInventory, } from './workspace-inventory.js';
5
+ import { buildAdminViewConfigEntry, buildAdminViewConfigSource, buildAdminViewEntrySource, buildAdminViewPhpSource, buildAdminViewRegistrySource, buildAdminViewScreenSource, buildAdminViewStyleSource, buildAdminViewTypesSource, buildCoreDataAdminViewDataSource, buildCoreDataAdminViewScreenSource, buildDefaultAdminViewDataSource, buildRestAdminViewDataSource, } from './cli-add-workspace-admin-view-templates.js';
6
+ import { ADMIN_VIEWS_PHP_GLOB, isAdminViewCoreDataSource, } from './cli-add-workspace-admin-view-types.js';
7
+ import { getWorkspaceBootstrapPath, patchFile, rollbackWorkspaceMutation, snapshotWorkspaceFiles, } from './cli-add-shared.js';
8
+ import { DEFAULT_WORDPRESS_CORE_DATA_VERSION, DEFAULT_WORDPRESS_DATA_VERSION, DEFAULT_WORDPRESS_DATAVIEWS_VERSION, DEFAULT_WP_TYPIA_DATAVIEWS_VERSION, resolveManagedPackageVersionRange, } from './package-versions.js';
9
+ import { findPhpFunctionRange, hasPhpFunctionDefinition, replacePhpFunctionDefinition, } from './php-utils.js';
10
+ function detectJsonIndent(source) {
11
+ const indentMatch = /\n([ \t]+)"/u.exec(source);
12
+ return indentMatch?.[1] ?? 2;
13
+ }
14
+ async function ensureAdminViewPackageDependencies(workspace, adminViewSource) {
15
+ const packageJsonPath = path.join(workspace.projectDir, 'package.json');
16
+ const wpTypiaDataViewsVersion = resolveManagedPackageVersionRange({
17
+ fallback: DEFAULT_WP_TYPIA_DATAVIEWS_VERSION,
18
+ packageName: '@wp-typia/dataviews',
19
+ workspacePackageDirName: 'wp-typia-dataviews',
20
+ });
21
+ const wordpressDataViewsVersion = resolveManagedPackageVersionRange({
22
+ fallback: DEFAULT_WORDPRESS_DATAVIEWS_VERSION,
23
+ packageName: '@wordpress/dataviews',
24
+ });
25
+ const wordpressCoreDataVersion = resolveManagedPackageVersionRange({
26
+ fallback: DEFAULT_WORDPRESS_CORE_DATA_VERSION,
27
+ packageName: '@wordpress/core-data',
28
+ });
29
+ const wordpressDataVersion = resolveManagedPackageVersionRange({
30
+ fallback: DEFAULT_WORDPRESS_DATA_VERSION,
31
+ packageName: '@wordpress/data',
32
+ });
33
+ await patchFile(packageJsonPath, (source) => {
34
+ const packageJson = JSON.parse(source);
35
+ const coreDataDependencies = isAdminViewCoreDataSource(adminViewSource)
36
+ ? {
37
+ '@wordpress/core-data': packageJson.dependencies?.['@wordpress/core-data'] ??
38
+ wordpressCoreDataVersion,
39
+ '@wordpress/data': packageJson.dependencies?.['@wordpress/data'] ??
40
+ wordpressDataVersion,
41
+ }
42
+ : {};
43
+ const nextDependencies = {
44
+ ...(packageJson.dependencies ?? {}),
45
+ '@wordpress/dataviews': packageJson.dependencies?.['@wordpress/dataviews'] ??
46
+ wordpressDataViewsVersion,
47
+ ...coreDataDependencies,
48
+ };
49
+ const nextDevDependencies = {
50
+ ...(packageJson.devDependencies ?? {}),
51
+ '@wp-typia/dataviews': packageJson.devDependencies?.['@wp-typia/dataviews'] ??
52
+ wpTypiaDataViewsVersion,
53
+ };
54
+ if (JSON.stringify(nextDependencies) ===
55
+ JSON.stringify(packageJson.dependencies ?? {}) &&
56
+ JSON.stringify(nextDevDependencies) ===
57
+ JSON.stringify(packageJson.devDependencies ?? {})) {
58
+ return source;
59
+ }
60
+ packageJson.dependencies = nextDependencies;
61
+ packageJson.devDependencies = nextDevDependencies;
62
+ return `${JSON.stringify(packageJson, null, detectJsonIndent(source))}\n`;
63
+ });
64
+ }
65
+ async function ensureAdminViewBootstrapAnchors(workspace) {
66
+ const bootstrapPath = getWorkspaceBootstrapPath(workspace);
67
+ await patchFile(bootstrapPath, (source) => {
68
+ let nextSource = source;
69
+ const loadFunctionName = `${workspace.workspace.phpPrefix}_load_admin_views`;
70
+ const loadHook = `add_action( 'plugins_loaded', '${loadFunctionName}' );`;
71
+ const loadHookPattern = new RegExp(`add_action\\(\\s*['"]plugins_loaded['"]\\s*,\\s*['"]${loadFunctionName}['"]\\s*\\)\\s*;`, 'u');
72
+ const loadFunction = `
73
+
74
+ function ${loadFunctionName}() {
75
+ \tforeach ( glob( __DIR__ . '${ADMIN_VIEWS_PHP_GLOB}' ) ?: array() as $admin_view_module ) {
76
+ \t\trequire_once $admin_view_module;
77
+ \t}
78
+ }
79
+ `;
80
+ const insertionAnchors = [
81
+ /add_action\(\s*["']init["']\s*,\s*["'][^"']+_load_textdomain["']\s*\);\s*\n/u,
82
+ /\?>\s*$/u,
83
+ ];
84
+ const insertPhpSnippet = (snippet) => {
85
+ for (const anchor of insertionAnchors) {
86
+ const candidate = nextSource.replace(anchor, (match) => `${snippet}\n${match}`);
87
+ if (candidate !== nextSource) {
88
+ nextSource = candidate;
89
+ return;
90
+ }
91
+ }
92
+ nextSource = `${nextSource.trimEnd()}\n${snippet}\n`;
93
+ };
94
+ const appendPhpSnippet = (snippet) => {
95
+ const closingTagPattern = /\?>\s*$/u;
96
+ if (closingTagPattern.test(nextSource)) {
97
+ nextSource = nextSource.replace(closingTagPattern, `${snippet}\n?>`);
98
+ return;
99
+ }
100
+ nextSource = `${nextSource.trimEnd()}\n${snippet}\n`;
101
+ };
102
+ if (!hasPhpFunctionDefinition(nextSource, loadFunctionName)) {
103
+ insertPhpSnippet(loadFunction);
104
+ }
105
+ else {
106
+ const functionRange = findPhpFunctionRange(nextSource, loadFunctionName);
107
+ const functionSource = functionRange
108
+ ? nextSource.slice(functionRange.start, functionRange.end)
109
+ : '';
110
+ if (!functionSource.includes(ADMIN_VIEWS_PHP_GLOB)) {
111
+ const replacedSource = replacePhpFunctionDefinition(nextSource, loadFunctionName, loadFunction);
112
+ if (!replacedSource) {
113
+ throw new Error(`Unable to repair ${path.basename(bootstrapPath)} for ${loadFunctionName}.`);
114
+ }
115
+ nextSource = replacedSource;
116
+ }
117
+ }
118
+ if (!loadHookPattern.test(nextSource)) {
119
+ appendPhpSnippet(loadHook);
120
+ }
121
+ return nextSource;
122
+ });
123
+ }
124
+ async function ensureAdminViewBuildScriptAnchors(workspace) {
125
+ const buildScriptPath = path.join(workspace.projectDir, 'scripts', 'build-workspace.mjs');
126
+ await patchFile(buildScriptPath, (source) => {
127
+ if (/['"]src\/admin-views\/index\.(?:ts|js)['"]/u.test(source)) {
128
+ return source;
129
+ }
130
+ const currentSharedEntriesPattern = /(\r?\n\s*['"]src\/editor-plugins\/index\.js['"])\s*,?/u;
131
+ let nextSource = source.replace(currentSharedEntriesPattern, `$1,
132
+ \t\t'src/admin-views/index.ts',
133
+ \t\t'src/admin-views/index.js',`);
134
+ if (nextSource !== source) {
135
+ return nextSource;
136
+ }
137
+ const legacySharedEntriesPattern = /\[\s*['"]src\/bindings\/index\.ts['"]\s*,\s*['"]src\/bindings\/index\.js['"]\s*(?:,\s*)?\]/u;
138
+ nextSource = source.replace(legacySharedEntriesPattern, `[
139
+ \t\t'src/bindings/index.ts',
140
+ \t\t'src/bindings/index.js',
141
+ \t\t'src/editor-plugins/index.ts',
142
+ \t\t'src/editor-plugins/index.js',
143
+ \t\t'src/admin-views/index.ts',
144
+ \t\t'src/admin-views/index.js',
145
+ \t]`);
146
+ if (nextSource !== source) {
147
+ return nextSource;
148
+ }
149
+ throw new Error(`Unable to update ${path.relative(workspace.projectDir, buildScriptPath)} for admin view shared entries.`);
150
+ });
151
+ }
152
+ async function ensureAdminViewWebpackAnchors(workspace) {
153
+ const webpackConfigPath = path.join(workspace.projectDir, 'webpack.config.js');
154
+ await patchFile(webpackConfigPath, (source) => {
155
+ if (/['"]admin-views\/index['"]/u.test(source)) {
156
+ return source;
157
+ }
158
+ const editorPluginEntryPattern = /(\n\s*\[\s*['"]editor-plugins\/index['"][\s\S]*?['"]src\/editor-plugins\/index\.js['"][\s\S]*?\]\s*\])\s*,?/u;
159
+ let nextSource = source.replace(editorPluginEntryPattern, `$1,
160
+ \t\t[
161
+ \t\t\t'admin-views/index',
162
+ \t\t\t[ 'src/admin-views/index.ts', 'src/admin-views/index.js' ],
163
+ \t\t],`);
164
+ if (nextSource !== source) {
165
+ return nextSource;
166
+ }
167
+ const legacySharedEntriesBlockPattern = /for\s*\(\s*const\s+relativePath\s+of\s+\[\s*['"]src\/bindings\/index\.ts['"]\s*,\s*['"]src\/bindings\/index\.js['"]\s*(?:,\s*)?\]\s*\)\s*\{[\s\S]*?entries\.push\(\s*\[\s*['"]bindings\/index['"]\s*,\s*entryPath\s*\]\s*\);\s*break;\s*\}/u;
168
+ const nextSharedEntriesBlock = `\tfor ( const [ entryName, candidates ] of [\n\t\t[\n\t\t\t'bindings/index',\n\t\t\t[ 'src/bindings/index.ts', 'src/bindings/index.js' ],\n\t\t],\n\t\t[\n\t\t\t'editor-plugins/index',\n\t\t\t[ 'src/editor-plugins/index.ts', 'src/editor-plugins/index.js' ],\n\t\t],\n\t\t[\n\t\t\t'admin-views/index',\n\t\t\t[ 'src/admin-views/index.ts', 'src/admin-views/index.js' ],\n\t\t],\n\t] ) {\n\t\tfor ( const relativePath of candidates ) {\n\t\t\tconst entryPath = path.resolve( process.cwd(), relativePath );\n\t\t\tif ( ! fs.existsSync( entryPath ) ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tentries.push( [ entryName, entryPath ] );\n\t\t\tbreak;\n\t\t}\n\t}`;
169
+ nextSource = source.replace(legacySharedEntriesBlockPattern, nextSharedEntriesBlock);
170
+ if (nextSource === source) {
171
+ throw new Error(`Unable to update ${path.relative(workspace.projectDir, webpackConfigPath)} for admin view shared entries.`);
172
+ }
173
+ return nextSource;
174
+ });
175
+ }
176
+ function resolveAdminViewRegistryPath(projectDir) {
177
+ const adminViewsDir = path.join(projectDir, 'src', 'admin-views');
178
+ return ([
179
+ path.join(adminViewsDir, 'index.ts'),
180
+ path.join(adminViewsDir, 'index.js'),
181
+ ].find((candidatePath) => fs.existsSync(candidatePath)) ??
182
+ path.join(adminViewsDir, 'index.ts'));
183
+ }
184
+ function readAdminViewRegistrySlugs(registryPath) {
185
+ if (!fs.existsSync(registryPath)) {
186
+ return [];
187
+ }
188
+ const source = fs.readFileSync(registryPath, 'utf8');
189
+ return Array.from(source.matchAll(/^\s*import\s+['"]\.\/([^/'"]+)(?:\/index(?:\.[cm]?[jt]sx?)?)?['"];?\s*$/gmu)).map((match) => match[1]);
190
+ }
191
+ async function writeAdminViewRegistry(projectDir, adminViewSlug) {
192
+ const adminViewsDir = path.join(projectDir, 'src', 'admin-views');
193
+ const registryPath = resolveAdminViewRegistryPath(projectDir);
194
+ await fsp.mkdir(adminViewsDir, { recursive: true });
195
+ const existingAdminViewSlugs = readWorkspaceInventory(projectDir).adminViews.map((entry) => entry.slug);
196
+ const existingRegistrySlugs = readAdminViewRegistrySlugs(registryPath);
197
+ const nextAdminViewSlugs = Array.from(new Set([
198
+ ...existingAdminViewSlugs,
199
+ ...existingRegistrySlugs,
200
+ adminViewSlug,
201
+ ])).sort();
202
+ await fsp.writeFile(registryPath, buildAdminViewRegistrySource(nextAdminViewSlugs), 'utf8');
203
+ }
204
+ export async function scaffoldAdminViewWorkspace(options) {
205
+ const { adminViewSlug, coreDataSource, parsedSource, restResource, workspace, } = options;
206
+ const blockConfigPath = path.join(workspace.projectDir, 'scripts', 'block-config.ts');
207
+ const bootstrapPath = getWorkspaceBootstrapPath(workspace);
208
+ const buildScriptPath = path.join(workspace.projectDir, 'scripts', 'build-workspace.mjs');
209
+ const packageJsonPath = path.join(workspace.projectDir, 'package.json');
210
+ const webpackConfigPath = path.join(workspace.projectDir, 'webpack.config.js');
211
+ const adminViewsIndexPath = resolveAdminViewRegistryPath(workspace.projectDir);
212
+ const adminViewDir = path.join(workspace.projectDir, 'src', 'admin-views', adminViewSlug);
213
+ const adminViewPhpPath = path.join(workspace.projectDir, 'inc', 'admin-views', `${adminViewSlug}.php`);
214
+ const mutationSnapshot = {
215
+ fileSources: await snapshotWorkspaceFiles([
216
+ adminViewsIndexPath,
217
+ blockConfigPath,
218
+ bootstrapPath,
219
+ buildScriptPath,
220
+ packageJsonPath,
221
+ webpackConfigPath,
222
+ ]),
223
+ snapshotDirs: [],
224
+ targetPaths: [adminViewDir, adminViewPhpPath],
225
+ };
226
+ try {
227
+ await fsp.mkdir(adminViewDir, { recursive: true });
228
+ await fsp.mkdir(path.dirname(adminViewPhpPath), { recursive: true });
229
+ await ensureAdminViewPackageDependencies(workspace, parsedSource);
230
+ await ensureAdminViewBootstrapAnchors(workspace);
231
+ await ensureAdminViewBuildScriptAnchors(workspace);
232
+ await ensureAdminViewWebpackAnchors(workspace);
233
+ await fsp.writeFile(path.join(adminViewDir, 'types.ts'), buildAdminViewTypesSource(adminViewSlug, restResource, coreDataSource), 'utf8');
234
+ await fsp.writeFile(path.join(adminViewDir, 'config.ts'), buildAdminViewConfigSource(adminViewSlug, workspace.workspace.textDomain, parsedSource, restResource), 'utf8');
235
+ await fsp.writeFile(path.join(adminViewDir, 'data.ts'), coreDataSource
236
+ ? buildCoreDataAdminViewDataSource(adminViewSlug, coreDataSource)
237
+ : restResource
238
+ ? buildRestAdminViewDataSource(adminViewSlug, restResource)
239
+ : buildDefaultAdminViewDataSource(adminViewSlug), 'utf8');
240
+ await fsp.writeFile(path.join(adminViewDir, 'Screen.tsx'), coreDataSource
241
+ ? buildCoreDataAdminViewScreenSource(adminViewSlug, workspace.workspace.textDomain)
242
+ : buildAdminViewScreenSource(adminViewSlug, workspace.workspace.textDomain), 'utf8');
243
+ await fsp.writeFile(path.join(adminViewDir, 'index.tsx'), buildAdminViewEntrySource(adminViewSlug), 'utf8');
244
+ await fsp.writeFile(path.join(adminViewDir, 'style.scss'), buildAdminViewStyleSource(), 'utf8');
245
+ await fsp.writeFile(adminViewPhpPath, buildAdminViewPhpSource(adminViewSlug, workspace), 'utf8');
246
+ await writeAdminViewRegistry(workspace.projectDir, adminViewSlug);
247
+ await appendWorkspaceInventoryEntries(workspace.projectDir, {
248
+ adminViewEntries: [
249
+ buildAdminViewConfigEntry(adminViewSlug, parsedSource),
250
+ ],
251
+ });
252
+ }
253
+ catch (error) {
254
+ await rollbackWorkspaceMutation(mutationSnapshot);
255
+ throw error;
256
+ }
257
+ }
@@ -0,0 +1,5 @@
1
+ import { type AdminViewRestResource, type AdminViewSource } from './cli-add-workspace-admin-view-types.js';
2
+ export declare function assertAdminViewPackageAvailability(): void;
3
+ export declare function parseAdminViewSource(source?: string): AdminViewSource | undefined;
4
+ export declare function resolveRestResourceSource(restResources: AdminViewRestResource[], source: AdminViewSource | undefined): AdminViewRestResource | undefined;
5
+ export declare function resolveAdminViewCoreDataSource(source: AdminViewSource | undefined): import("./cli-add-workspace-admin-view-types.js").AdminViewCoreDataSource | undefined;
@@ -0,0 +1,86 @@
1
+ import { assertValidGeneratedSlug } from './cli-add-shared.js';
2
+ import { CLI_DIAGNOSTIC_CODES, createCliDiagnosticCodeError, } from './cli-diagnostics.js';
3
+ import { ADMIN_VIEW_ALLOW_UNPUBLISHED_DATAVIEWS_ENV, ADMIN_VIEW_CORE_DATA_ENTITY_KIND_IDS, ADMIN_VIEW_CORE_DATA_ENTITY_NAME_PATTERN, ADMIN_VIEW_CORE_DATA_ENTITY_SEGMENT_PATTERN, ADMIN_VIEW_CORE_DATA_SOURCE_KIND, ADMIN_VIEW_PUBLIC_INSTALLS_ENABLED, ADMIN_VIEW_REST_SOURCE_KIND, ADMIN_VIEW_SOURCE_USAGE, isAdminViewCoreDataSource, isAdminViewRestResourceSource, } from './cli-add-workspace-admin-view-types.js';
4
+ function isAdminViewUnpublishedDataViewsOverrideEnabled() {
5
+ return (process.env[ADMIN_VIEW_ALLOW_UNPUBLISHED_DATAVIEWS_ENV]?.trim() === '1');
6
+ }
7
+ export function assertAdminViewPackageAvailability() {
8
+ if (isAdminViewUnpublishedDataViewsOverrideEnabled() ||
9
+ ADMIN_VIEW_PUBLIC_INSTALLS_ENABLED) {
10
+ return;
11
+ }
12
+ throw createCliDiagnosticCodeError(CLI_DIAGNOSTIC_CODES.INVALID_ARGUMENT, '`wp-typia add admin-view` is temporarily unavailable because `@wp-typia/dataviews` is not published to npm for public installs yet.');
13
+ }
14
+ function assertValidCoreDataEntitySegment(label, value) {
15
+ const trimmed = value.trim();
16
+ if (!trimmed) {
17
+ throw new Error(`${label} is required. Use \`${ADMIN_VIEW_SOURCE_USAGE}\`.`);
18
+ }
19
+ if (!ADMIN_VIEW_CORE_DATA_ENTITY_SEGMENT_PATTERN.test(trimmed)) {
20
+ throw new Error(`${label} must start with a letter and contain only letters, numbers, underscores, or hyphens.`);
21
+ }
22
+ return trimmed;
23
+ }
24
+ function assertValidCoreDataEntityName(value) {
25
+ const normalized = value.trim();
26
+ if (!normalized) {
27
+ throw new Error(`Admin view source entity name is required. Use \`${ADMIN_VIEW_SOURCE_USAGE}\`.`);
28
+ }
29
+ if (!ADMIN_VIEW_CORE_DATA_ENTITY_NAME_PATTERN.test(normalized)) {
30
+ throw new Error('Admin view source entity name must start with a lowercase letter or number and contain only lowercase letters, numbers, underscores, or hyphens.');
31
+ }
32
+ return normalized;
33
+ }
34
+ function assertValidCoreDataEntityKind(value) {
35
+ const normalized = assertValidCoreDataEntitySegment('Admin view source entity kind', value);
36
+ if (!ADMIN_VIEW_CORE_DATA_ENTITY_KIND_IDS.includes(normalized)) {
37
+ throw new Error(`Admin view core-data sources currently support only: ${ADMIN_VIEW_CORE_DATA_ENTITY_KIND_IDS.join(', ')}.`);
38
+ }
39
+ return normalized;
40
+ }
41
+ export function parseAdminViewSource(source) {
42
+ const trimmed = source?.trim();
43
+ if (!trimmed) {
44
+ return undefined;
45
+ }
46
+ const separatorIndex = trimmed.indexOf(':');
47
+ const kind = separatorIndex === -1 ? trimmed : trimmed.slice(0, separatorIndex);
48
+ const locator = separatorIndex === -1 ? '' : trimmed.slice(separatorIndex + 1);
49
+ if (!locator) {
50
+ throw new Error('Admin view source must use `rest-resource:<slug>` or `core-data:<kind>/<name>`.');
51
+ }
52
+ if (kind === ADMIN_VIEW_REST_SOURCE_KIND) {
53
+ return {
54
+ kind,
55
+ slug: assertValidGeneratedSlug('Admin view source slug', locator, ADMIN_VIEW_SOURCE_USAGE),
56
+ };
57
+ }
58
+ if (kind === ADMIN_VIEW_CORE_DATA_SOURCE_KIND) {
59
+ const [entityKind, entityName, extra] = locator.split('/');
60
+ if (!entityKind || !entityName || extra !== undefined) {
61
+ throw new Error('Admin view core-data sources must use `core-data:<kind>/<name>`, for example `core-data:postType/post`.');
62
+ }
63
+ return {
64
+ entityKind: assertValidCoreDataEntityKind(entityKind),
65
+ entityName: assertValidCoreDataEntityName(entityName),
66
+ kind,
67
+ };
68
+ }
69
+ throw new Error('Admin view source must use `rest-resource:<slug>` or `core-data:<kind>/<name>`.');
70
+ }
71
+ export function resolveRestResourceSource(restResources, source) {
72
+ if (!isAdminViewRestResourceSource(source)) {
73
+ return undefined;
74
+ }
75
+ const restResource = restResources.find((entry) => entry.slug === source.slug);
76
+ if (!restResource) {
77
+ throw new Error(`Unknown REST resource source "${source.slug}". Choose one of: ${restResources.map((entry) => entry.slug).join(', ') || '<none>'}.`);
78
+ }
79
+ if (!restResource.methods.includes('list')) {
80
+ throw new Error(`REST resource source "${source.slug}" must include the list method for DataViews pagination.`);
81
+ }
82
+ return restResource;
83
+ }
84
+ export function resolveAdminViewCoreDataSource(source) {
85
+ return isAdminViewCoreDataSource(source) ? source : undefined;
86
+ }
@@ -0,0 +1,23 @@
1
+ import { type WorkspaceProject } from './workspace-project.js';
2
+ import { type AdminViewCoreDataSource, type AdminViewRestResource, type AdminViewSource } from './cli-add-workspace-admin-view-types.js';
3
+ export declare function buildAdminViewConfigEntry(adminViewSlug: string, source: AdminViewSource | undefined): string;
4
+ export declare function buildAdminViewRegistrySource(adminViewSlugs: string[]): string;
5
+ /**
6
+ * Build the generated admin-view item and dataset types for the selected source.
7
+ */
8
+ export declare function buildAdminViewTypesSource(adminViewSlug: string, restResource: AdminViewRestResource | undefined, coreDataSource: AdminViewCoreDataSource | undefined): string;
9
+ /**
10
+ * Build the generated DataViews config source for an admin-view scaffold.
11
+ */
12
+ export declare function buildAdminViewConfigSource(adminViewSlug: string, textDomain: string, source: AdminViewSource | undefined, restResource: AdminViewRestResource | undefined): string;
13
+ export declare function buildDefaultAdminViewDataSource(adminViewSlug: string): string;
14
+ export declare function buildRestAdminViewDataSource(adminViewSlug: string, restResource: AdminViewRestResource): string;
15
+ /**
16
+ * Build a core-data-backed admin-view data module for a supported entity family.
17
+ */
18
+ export declare function buildCoreDataAdminViewDataSource(adminViewSlug: string, coreDataSource: AdminViewCoreDataSource): string;
19
+ export declare function buildAdminViewScreenSource(adminViewSlug: string, textDomain: string): string;
20
+ export declare function buildCoreDataAdminViewScreenSource(adminViewSlug: string, textDomain: string): string;
21
+ export declare function buildAdminViewEntrySource(adminViewSlug: string): string;
22
+ export declare function buildAdminViewStyleSource(): string;
23
+ export declare function buildAdminViewPhpSource(adminViewSlug: string, workspace: WorkspaceProject): string;