@contentrain/wp-import 0.7.0 → 0.9.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.
- package/README.md +106 -0
- package/dist/index.d.mts +16 -0
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +908 -54
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -120,6 +120,14 @@ block refers to it; an empty navigation block without a `ref` shows the most
|
|
|
120
120
|
recent published one, as WordPress does. Block menu items have no WordPress id
|
|
121
121
|
and get negative ids; the store claims no `wp_id` for them.
|
|
122
122
|
|
|
123
|
+
A navigation block in a template part that carries its own links (an inline
|
|
124
|
+
navigation, as in Twenty Twenty-Five's footer columns) is a menu of that part's
|
|
125
|
+
area: `Footer navigation 1`, `2`, … (its `ariaLabel` names it when set), links
|
|
126
|
+
in order and nested. Only template parts a template uses count — a theme ships
|
|
127
|
+
alternatives (`footer-columns`, `header-large-title`) that no page shows; without
|
|
128
|
+
the templates, the part named after its area (`header`, `footer`). A `#` link
|
|
129
|
+
stays `#`. Inline menus have no WordPress record: negative ids, no `wp_id`.
|
|
130
|
+
|
|
123
131
|
A menu item that is itself a draft, or whose post target is not proven public
|
|
124
132
|
— a draft, pending, private, scheduled or password-protected post, or one this
|
|
125
133
|
import never read (a type outside REST, a listing past a page cap) — is left
|
|
@@ -132,6 +140,104 @@ contains `menus_require_auth` — an empty menu list is never presented as the
|
|
|
132
140
|
site having none. The `menus` model gains a `locations` field only when the
|
|
133
141
|
source named them.
|
|
134
142
|
|
|
143
|
+
A menu item that names a public post or term links to that post's or term's
|
|
144
|
+
public address (its REST `link`). The address the item stored is not used: a
|
|
145
|
+
block keeps the URL it had when it was saved, and a hand-typed `?page_id=` is a
|
|
146
|
+
form the migrated site cannot serve. A hand-typed `?page_id=` / `?p=` counts
|
|
147
|
+
as this site's with or without a leading `www.`.
|
|
148
|
+
|
|
149
|
+
### Redirects over REST
|
|
150
|
+
|
|
151
|
+
REST reads one source of redirects: the Redirection plugin (`redirection/v1`).
|
|
152
|
+
This needs an application password of a user who may manage the plugin. Its
|
|
153
|
+
rules are shaped as the Bridge shapes them. Each rule lands in exactly one of
|
|
154
|
+
two places:
|
|
155
|
+
|
|
156
|
+
- `redirects`: the rules the site serves, with the plugin's query, case and
|
|
157
|
+
trailing-slash modes. A "gone" rule (410, 451) is served with an empty `to`.
|
|
158
|
+
- `redirects_excluded`: every other rule, with its reason (disabled,
|
|
159
|
+
conditional, a 404 or pass-through action).
|
|
160
|
+
|
|
161
|
+
Yoast Premium, Rank Math, Safe Redirect Manager and `.htaccess` keep their
|
|
162
|
+
rules where only the Bridge export reads them. So `gaps` always contains
|
|
163
|
+
`redirects_partial`. It also contains `redirects_require_auth` when the site
|
|
164
|
+
runs Redirection but its rules could not be read with the credential given.
|
|
165
|
+
|
|
166
|
+
A conditional rule (login, cookie, header, IP, role…) is excluded. Only a login
|
|
167
|
+
rule keeps its `condition`, which is its two addresses. Any other condition
|
|
168
|
+
holds the value a visitor must present, often a secret, so it is never
|
|
169
|
+
exported; the reason names its type.
|
|
170
|
+
|
|
171
|
+
Each attachment carries its attachment page as `link`, so the migrated site
|
|
172
|
+
can redirect it. The link is kept only when the attachment has no parent or
|
|
173
|
+
its parent is proven public, because the page sits under the parent's address
|
|
174
|
+
and would otherwise carry a draft's, a private post's or a scheduled post's
|
|
175
|
+
slug.
|
|
176
|
+
|
|
177
|
+
### ACF fields, custom post types and taxonomies over REST
|
|
178
|
+
|
|
179
|
+
ACF / Secure Custom Fields values arrive on a post's `acf` key — only for field
|
|
180
|
+
groups set to "Show in REST API" (off by default). Each field is typed by one
|
|
181
|
+
versioned table (`ACF_MAPPING_VERSION`, exported with `ACF_SCALAR_TYPES` and
|
|
182
|
+
`ACF_REFERENCE_TYPES`): the ACF type is read from SCF's `<name>_source.type`
|
|
183
|
+
where the site states it, and inferred from the value's shape only when nothing
|
|
184
|
+
states it (the field description then says so).
|
|
185
|
+
|
|
186
|
+
| ACF | Contentrain |
|
|
187
|
+
| --- | --- |
|
|
188
|
+
| text, time picker | `string` |
|
|
189
|
+
| textarea | `text` |
|
|
190
|
+
| wysiwyg | `richtext` |
|
|
191
|
+
| email / url, oembed / number, range / true false | `email` / `url` / `number` / `boolean` |
|
|
192
|
+
| date picker / date time picker | `date` / `datetime` (ISO, with the site's offset) |
|
|
193
|
+
| color picker / icon picker | `color` / `icon` |
|
|
194
|
+
| select, radio, button group | `select` (its choices) |
|
|
195
|
+
| checkbox, multiple select | `array` of `select` |
|
|
196
|
+
| image / file | `image` / `file` (the URL) |
|
|
197
|
+
| link | `object { url, title, target }` |
|
|
198
|
+
| google map | `object { address, lat, lng, zoom }` |
|
|
199
|
+
| group | `object` of its fields |
|
|
200
|
+
| repeater | `array` of `object` (nested repeaters nest) |
|
|
201
|
+
| flexible content | `array` of `object`: a required `layout` select plus the union of the layouts' fields |
|
|
202
|
+
| post object, relationship | `relation` / `relations` to the entries' models |
|
|
203
|
+
| taxonomy / user / gallery | `relations` to the term model / `authors` / media |
|
|
204
|
+
| page link | `url`: the target's address, only when the target is published and unprotected |
|
|
205
|
+
| tab, accordion, message | nothing (layout only) |
|
|
206
|
+
| password | nothing, ever |
|
|
207
|
+
|
|
208
|
+
Sub-fields of a repeater, group or flexible layout are typed by the same table
|
|
209
|
+
when the site states their type (SCF's `_source` inside each row); a reference
|
|
210
|
+
inside a row, and a sub-field with no stated type, are typed from the value. A
|
|
211
|
+
select or checkbox value outside the field's stated choices is left out and
|
|
212
|
+
counted in the report's `acf_outside_choices`. A date time picker's value is written
|
|
213
|
+
with the site's UTC offset for that moment, DST included (the `/wp-json/`
|
|
214
|
+
index's `timezone_string`, else `gmt_offset`); with neither it stays local and
|
|
215
|
+
`acf_datetime_unzoned` counts it. `src/fixtures/acf-parity.json`
|
|
216
|
+
holds the cases the Contentrain Bridge must map the same way.
|
|
217
|
+
|
|
218
|
+
**A password field is never read** — at any depth: a password sub-field of a
|
|
219
|
+
repeater row, a group or a flexible layout is removed with its `_source` before
|
|
220
|
+
the value reaches `RawIR`. Where the source states the type, the type decides;
|
|
221
|
+
where it does not (plain ACF, no `<name>_source`), a field whose name has a
|
|
222
|
+
secret word in it (`password`, `user_pass`, `apiKey`, `access_token`, …; whole
|
|
223
|
+
words, so `passage` stays) is skipped instead. It never reaches `RawIR`, the
|
|
224
|
+
store, or a report.
|
|
225
|
+
|
|
226
|
+
ACF values follow their post: a draft's fields land in the store with the
|
|
227
|
+
draft (meta `status: draft`), like its body. A reference to an entry the import
|
|
228
|
+
did not read is dropped and counted in `dropped_relations`. The report's
|
|
229
|
+
`acf_fields` lists each field's type. When any post carries an `acf` key, the
|
|
230
|
+
result's `gaps` contains `acf_partial`: groups without REST exposure, options
|
|
231
|
+
pages and fields on post types outside REST are not visible to REST — the
|
|
232
|
+
Bridge reads those.
|
|
233
|
+
|
|
234
|
+
With an Application Password, post types are read with `context=edit` so their
|
|
235
|
+
`viewable` flag is known: a type that is in REST but not publicly queryable (a
|
|
236
|
+
testimonial post type, say) keeps its content but gets no address (`link` is
|
|
237
|
+
null), so no route or redirect claims a page that does not exist. Custom
|
|
238
|
+
taxonomies in REST are read with their terms, and a post's terms in them become
|
|
239
|
+
its relations.
|
|
240
|
+
|
|
135
241
|
|
|
136
242
|
### Publication and translation identity
|
|
137
243
|
|
package/dist/index.d.mts
CHANGED
|
@@ -71,6 +71,13 @@ interface RestImportResult {
|
|
|
71
71
|
* What this rung could not read, as codes a caller can act on (the text is in `warnings`).
|
|
72
72
|
* `menus_require_auth`: menus and block navigation are only readable with an application password
|
|
73
73
|
* of a user who may edit theme options — none was given, the site rejected it, or it lacks that right.
|
|
74
|
+
* `redirects_partial`: always, over REST — it reads only the Redirection plugin's rules; Yoast Premium, Rank Math,
|
|
75
|
+
* Safe Redirect Manager and `.htaccess` keep theirs where only the Bridge export reads them.
|
|
76
|
+
* `redirects_require_auth`: the site runs Redirection, and its rules need an application password of a user who
|
|
77
|
+
* may manage it — none was given, the site rejected it, or it lacks that right.
|
|
78
|
+
* `acf_partial`: the site runs ACF / Secure Custom Fields; REST shows only the field groups set to
|
|
79
|
+
* `show_in_rest` (off by default) and no options page — the Bridge export reads the rest. Where the site
|
|
80
|
+
* states no field types (plain ACF, no `<name>_source`), a secret field is recognised by its name only.
|
|
74
81
|
*/
|
|
75
82
|
gaps: string[];
|
|
76
83
|
}
|
|
@@ -83,6 +90,10 @@ interface ImportReport {
|
|
|
83
90
|
title_fallback: number;
|
|
84
91
|
meta_fields: Record<string, string>;
|
|
85
92
|
acf_fields: Record<string, string>;
|
|
93
|
+
/** ACF select/checkbox values outside their field's stated choices, left out (`field: count`). */
|
|
94
|
+
acf_outside_choices: Record<string, number>;
|
|
95
|
+
/** ACF date-times written without a zone because the source named none (`timezone_string` / `gmt_offset`). */
|
|
96
|
+
acf_datetime_unzoned: number;
|
|
86
97
|
skipped_types: string[];
|
|
87
98
|
dropped_relations: number;
|
|
88
99
|
models: Record<string, {
|
|
@@ -102,6 +113,11 @@ interface ImportReport {
|
|
|
102
113
|
* put that text on a public site. Publish only after deciding what to show.
|
|
103
114
|
*/
|
|
104
115
|
password_protected_drafts: number;
|
|
116
|
+
/**
|
|
117
|
+
* The source named no site title (no REST index name, no WXR channel title): the `site` entry has no
|
|
118
|
+
* `title`. The field stays required, so the store says what is missing rather than inventing a name.
|
|
119
|
+
*/
|
|
120
|
+
site_title_missing: boolean;
|
|
105
121
|
}
|
|
106
122
|
interface ContentrainResult {
|
|
107
123
|
files: Record<string, string>;
|
package/dist/index.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/wxr.ts","../src/rest.ts","../src/contentrain.ts","../src/comments.ts","../src/php-unserialize.ts","../src/core.ts","../src/delta.ts"],"mappings":";;;;UA2BiB,QAAA;EACf,UAAA;IAAc,QAAA;IAAkB,OAAA;IAAiB,MAAA;IAAgB,IAAA;EAAA;EACjE,UAAA;EACA,gBAAA;EACA,MAAA,EAAQ,MAAA;AAAA;AAAA,UAGO,cAAA;EACf,GAAA,EAAK,KAAA;EACL,KAAA,EAAO,QAAA;AAAA;AAAA,iBAiBa,QAAA,CAAS,KAAA,WAAgB,QAAA,EAAU,IAAA;EAAS,IAAA;AAAA,IAAkB,OAAA,CAAQ,cAAA;;;
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/wxr.ts","../src/rest.ts","../src/contentrain.ts","../src/comments.ts","../src/php-unserialize.ts","../src/core.ts","../src/delta.ts"],"mappings":";;;;UA2BiB,QAAA;EACf,UAAA;IAAc,QAAA;IAAkB,OAAA;IAAiB,MAAA;IAAgB,IAAA;EAAA;EACjE,UAAA;EACA,gBAAA;EACA,MAAA,EAAQ,MAAA;AAAA;AAAA,UAGO,cAAA;EACf,GAAA,EAAK,KAAA;EACL,KAAA,EAAO,QAAA;AAAA;AAAA,iBAiBa,QAAA,CAAS,KAAA,WAAgB,QAAA,EAAU,IAAA;EAAS,IAAA;AAAA,IAAkB,OAAA,CAAQ,cAAA;;;UCnC3E,iBAAA;EACf,MAAA;;EAEA,SAAA,UAAmB,KAAA;EDMI;;;;;;;;ECGvB,IAAA;IAAS,IAAA;IAAc,WAAA;EAAA;EACvB,OAAA;EDAc;AAGhB;;;;ECGE,WAAA;EDFK;;;;ECOL,QAAA;EACA,IAAA;AAAA;AAAA,UAGe,gBAAA;EACf,GAAA,EAAK,KAAA;EACL,QAAA;EDKkF;;;;;;;;ECIlF,UAAA;IAAc,MAAA;IAA0C,SAAA;EAAA;;;AAvC1D;;;;;;;;;;EAoDE,IAAA;AAAA;AAAA,iBA2EoB,cAAA,CAAe,OAAA,EAAS,iBAAA,GAAoB,OAAA,CAAQ,gBAAA;;;UCrHzD,YAAA;EACf,cAAA;EACA,aAAA;EACA,cAAA;EACA,WAAA,EAAa,MAAA;EACb,UAAA,EAAY,MAAA;EFFE;EEId,mBAAA,EAAqB,MAAA;EFPP;EESd,oBAAA;EACA,aAAA;EACA,iBAAA;EACA,MAAA,EAAQ,MAAA;IAAiB,IAAA;IAAc,MAAA;IAAgB,MAAA;IAAgB,OAAA;EAAA;EFNxD;EEQf,OAAA;;EAEA,kBAAA;EFTA;;;;;;EEgBA,yBAAA;EFE4B;;;;EEG5B,kBAAA;AAAA;AAAA,UAGe,iBAAA;EACf,KAAA,EAAO,MAAA;EACP,gBAAA,EAAkB,cAAA;EAClB,MAAA,EAAQ,YAAA;AAAA;AAAA,iBA0CM,gBAAA,CAAiB,GAAA,EAAK,KAAA,EAAO,IAAA;EAAS,SAAA;AAAA,IAAuB,iBAAA;;;;;;AF7E7E;;;iBGbgB,cAAA,CAAe,GAAA,EAAK,KAAA;EAAU,QAAA,EAAU,UAAA;EAAc,QAAA,EAAU,WAAA,CAAY,cAAA;AAAA;AAAA,iBAgB5E,mBAAA,CAAoB,GAAA,EAAK,KAAA,EAAO,OAAA,EAAS,cAAA,EAAgB,IAAA;EAAS,YAAA;AAAA,IAA0B,cAAA;;iBAiB5F,iBAAA,CAAkB,GAAA,EAAK,cAAA,GAAiB,eAAA;;;UC3CvC,iBAAA;EACf,EAAA;EACA,UAAA;EACA,KAAA;EACA,KAAA;AAAA;AAAA,iBAGc,eAAA,CAAgB,CAAA,YAAa,CAAA;AAAA,iBAI7B,cAAA,CAAe,GAAA;;iBAyFf,cAAA,CAAe,CAAA,WAAY,iBAAA;;;cC9F9B,KAAA,GAAS,CAAA;;cAST,KAAA,GAAS,CAAA;;cAcT,KAAA,GAAS,CAAA;;;;;;;;;ALCtB;cK8Ba,UAAA,EAAU,MAAA;;cAIV,WAAA,EAAW,MAAA;;cAOX,UAAA,GAAc,CAAA;AAAA,cAGd,OAAA,GAAW,CAAA;;;;UC3DP,UAAA;EACf,KAAA,EAAO,MAAA;EACP,gBAAA,EAAkB,cAAA;AAAA;AAAA,UAGH,oBAAA;ENOD;EMLd,KAAA,EAAO,eAAA;ENEO;EMAd,KAAA,EAAO,UAAA;ENA0C;EMEjD,QAAA,GAAW,UAAA;ENDX;;;;;EMOA,UAAA;ENFe;;;;EMOf,SAAA;AAAA;AAAA,cAGW,kBAAA;AAAA,cACA,iBAAA;;;ANQb;;;;;;;;;;iBM8NgB,eAAA,CAAgB,KAAA,EAAO,oBAAA,GAAuB,eAAA;;iBAkC9C,uBAAA,CAAwB,IAAA,EAAM,eAAA"}
|