contentful-import 10.2.0 → 10.2.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.
package/README.md CHANGED
@@ -235,7 +235,7 @@ contentfulImport({
235
235
 
236
236
  ### Embargoed Assets
237
237
 
238
- If a space is configured to use the [embargoed assets feature](https://www.contentful.com/help/media/embargoed-assets/), certain options will need to be set to use the export/import tooling. When exporting content ([using `contentful-export`](https://github.com/contentful/contentful-export)), the `downloadAssets` option must be set to `true`. This will download the asset files to your local machine. Then, when importing content, the `uploadAssets` option must be set to `true` and the `assetsDirectory` must be set to the directory that contains all of the exported asset folders.
238
+ If a space is configured to use the [embargoed assets feature](https://www.contentful.com/help/media/embargoed-assets/), export with `downloadAssets: true` and import with `uploadAssets: true` and `assetsDirectory` pointing to the directory generated by the export. Embargoed asset URLs cannot be processed directly during import; the importer now fails before making API calls and prints the required options when the local upload options are missing.
239
239
 
240
240
  ```javascript
241
241
  const contentfulImport = require('contentful-import')
@@ -245,7 +245,7 @@ const options = {
245
245
  spaceId: '<space_id>',
246
246
  managementToken: '<content_management_api_key>',
247
247
  uploadAssets: true,
248
- assetsDirectory: '/path/to/exported/assets.json'
248
+ assetsDirectory: '/path/to/exported-assets'
249
249
  }
250
250
 
251
251
  contentfulImport(options)
package/dist/index.js CHANGED
@@ -2261,6 +2261,34 @@ function getHeadersConfig(value) {
2261
2261
  var import_proxy = require("contentful-batch-libs/dist/proxy");
2262
2262
  var import_add_sequence_header = __toESM(require("contentful-batch-libs/dist/add-sequence-header"));
2263
2263
  var import_json_ext = require("@discoveryjs/json-ext");
2264
+
2265
+ // lib/utils/embargoed-assets.ts
2266
+ var EMBARGOED_ASSET_HOST_PATTERN = /^[^.]+\.secure\.ctfassets\.net$/i;
2267
+ function getHostname(url) {
2268
+ try {
2269
+ const normalizedUrl = url.startsWith("//") ? `https:${url}` : url;
2270
+ return new URL(normalizedUrl).hostname;
2271
+ } catch {
2272
+ return void 0;
2273
+ }
2274
+ }
2275
+ function isEmbargoedAssetUrl(url) {
2276
+ if (typeof url !== "string") {
2277
+ return false;
2278
+ }
2279
+ const hostname = getHostname(url);
2280
+ return hostname ? EMBARGOED_ASSET_HOST_PATTERN.test(hostname) : false;
2281
+ }
2282
+ function getEmbargoedAssetCount(content) {
2283
+ return (content.assets || []).reduce((count, asset) => {
2284
+ const embargoedAssetFiles = Object.values(asset.fields?.file || {}).filter((file) => {
2285
+ return isEmbargoedAssetUrl(file?.url) || isEmbargoedAssetUrl(file?.upload);
2286
+ });
2287
+ return count + embargoedAssetFiles.length;
2288
+ }, 0);
2289
+ }
2290
+
2291
+ // lib/parseOptions.ts
2264
2292
  var SUPPORTED_ENTITY_TYPES = [
2265
2293
  "contentTypes",
2266
2294
  "tags",
@@ -2313,6 +2341,12 @@ async function parseOptions(params) {
2313
2341
  if (options.skipLocales && !options.contentModelOnly) {
2314
2342
  throw new Error("`skipLocales` can only be used together with `contentModelOnly`");
2315
2343
  }
2344
+ if (options.uploadAssets && !options.assetsDirectory) {
2345
+ throw new Error("`uploadAssets` requires `assetsDirectory`");
2346
+ }
2347
+ if (options.assetsDirectory && !options.uploadAssets) {
2348
+ throw new Error("`assetsDirectory` requires `uploadAssets`");
2349
+ }
2316
2350
  const proxySimpleExp = /.+:\d+/;
2317
2351
  const proxyAuthExp = /.+:.+@.+:\d+/;
2318
2352
  if (typeof options.proxy === "string" && options.proxy && !(proxySimpleExp.test(options.proxy) || proxyAuthExp.test(options.proxy))) {
@@ -2337,6 +2371,14 @@ async function parseOptions(params) {
2337
2371
  SUPPORTED_ENTITY_TYPES.forEach((type) => {
2338
2372
  options.content[type] = options.content[type] || [];
2339
2373
  });
2374
+ if (!options.uploadAssets && !options.contentModelOnly) {
2375
+ const embargoedAssetCount = getEmbargoedAssetCount(options.content);
2376
+ if (embargoedAssetCount) {
2377
+ throw new Error(
2378
+ `Found ${embargoedAssetCount} embargoed asset file${embargoedAssetCount === 1 ? "" : "s"} in the import data. Embargoed asset URLs cannot be processed directly during import. Re-export with \`contentful space export --download-assets\`, then import with \`--upload-assets --assets-directory <export-directory>\`. For library usage, set \`uploadAssets: true\` and \`assetsDirectory\`.`
2379
+ );
2380
+ }
2381
+ }
2340
2382
  if (typeof options.proxy === "string") {
2341
2383
  options.proxy = (0, import_proxy.proxyStringToObject)(options.proxy);
2342
2384
  }
package/dist/index.mjs CHANGED
@@ -2231,6 +2231,34 @@ function getHeadersConfig(value) {
2231
2231
  import { proxyStringToObject, agentFromProxy } from "contentful-batch-libs/dist/proxy";
2232
2232
  import addSequenceHeader from "contentful-batch-libs/dist/add-sequence-header";
2233
2233
  import { parseChunked } from "@discoveryjs/json-ext";
2234
+
2235
+ // lib/utils/embargoed-assets.ts
2236
+ var EMBARGOED_ASSET_HOST_PATTERN = /^[^.]+\.secure\.ctfassets\.net$/i;
2237
+ function getHostname(url) {
2238
+ try {
2239
+ const normalizedUrl = url.startsWith("//") ? `https:${url}` : url;
2240
+ return new URL(normalizedUrl).hostname;
2241
+ } catch {
2242
+ return void 0;
2243
+ }
2244
+ }
2245
+ function isEmbargoedAssetUrl(url) {
2246
+ if (typeof url !== "string") {
2247
+ return false;
2248
+ }
2249
+ const hostname = getHostname(url);
2250
+ return hostname ? EMBARGOED_ASSET_HOST_PATTERN.test(hostname) : false;
2251
+ }
2252
+ function getEmbargoedAssetCount(content) {
2253
+ return (content.assets || []).reduce((count, asset) => {
2254
+ const embargoedAssetFiles = Object.values(asset.fields?.file || {}).filter((file) => {
2255
+ return isEmbargoedAssetUrl(file?.url) || isEmbargoedAssetUrl(file?.upload);
2256
+ });
2257
+ return count + embargoedAssetFiles.length;
2258
+ }, 0);
2259
+ }
2260
+
2261
+ // lib/parseOptions.ts
2234
2262
  var SUPPORTED_ENTITY_TYPES = [
2235
2263
  "contentTypes",
2236
2264
  "tags",
@@ -2283,6 +2311,12 @@ async function parseOptions(params) {
2283
2311
  if (options.skipLocales && !options.contentModelOnly) {
2284
2312
  throw new Error("`skipLocales` can only be used together with `contentModelOnly`");
2285
2313
  }
2314
+ if (options.uploadAssets && !options.assetsDirectory) {
2315
+ throw new Error("`uploadAssets` requires `assetsDirectory`");
2316
+ }
2317
+ if (options.assetsDirectory && !options.uploadAssets) {
2318
+ throw new Error("`assetsDirectory` requires `uploadAssets`");
2319
+ }
2286
2320
  const proxySimpleExp = /.+:\d+/;
2287
2321
  const proxyAuthExp = /.+:.+@.+:\d+/;
2288
2322
  if (typeof options.proxy === "string" && options.proxy && !(proxySimpleExp.test(options.proxy) || proxyAuthExp.test(options.proxy))) {
@@ -2307,6 +2341,14 @@ async function parseOptions(params) {
2307
2341
  SUPPORTED_ENTITY_TYPES.forEach((type) => {
2308
2342
  options.content[type] = options.content[type] || [];
2309
2343
  });
2344
+ if (!options.uploadAssets && !options.contentModelOnly) {
2345
+ const embargoedAssetCount = getEmbargoedAssetCount(options.content);
2346
+ if (embargoedAssetCount) {
2347
+ throw new Error(
2348
+ `Found ${embargoedAssetCount} embargoed asset file${embargoedAssetCount === 1 ? "" : "s"} in the import data. Embargoed asset URLs cannot be processed directly during import. Re-export with \`contentful space export --download-assets\`, then import with \`--upload-assets --assets-directory <export-directory>\`. For library usage, set \`uploadAssets: true\` and \`assetsDirectory\`.`
2349
+ );
2350
+ }
2351
+ }
2310
2352
  if (typeof options.proxy === "string") {
2311
2353
  options.proxy = proxyStringToObject(options.proxy);
2312
2354
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "contentful-import",
3
- "version": "10.2.0",
3
+ "version": "10.2.1",
4
4
  "description": "this tool allows you to import JSON dump exported by contentful-export",
5
5
  "main": "dist/index.mjs",
6
6
  "typings": "dist/index.d.ts",