diff --git a/README.md b/README.md index f21d491e..0a09dde2 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,14 @@ Contentstack is a headless CMS with an API-first approach. It is a CMS that deve |referenceDepth|number|2|**Optional** The default nested-reference-field depth that'd be considered when calling .includeReferences(). This can be overridden by passing a numerical argument to .includeReferences(4)| |projections|object|{_content_type_uid: 0}|**Optional** Keys that by default would be removed from results. Pass `key: 0` to remove, `key: 1` to override the existing..| +### Environment Variables + +The SDK supports the following environment variables for advanced configuration: + +| Variable | Description | +|-------------|-------------| +| `APP_ROOT` | (Optional) Sets the root directory for content storage. If not set, defaults to the current working directory. | + ### Config Overview Here's an overview of the SDK's configurable properties diff --git a/package-lock.json b/package-lock.json index d3d7fa86..25bf74c3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@contentstack/datasync-filesystem-sdk", - "version": "1.1.0", + "version": "1.2.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@contentstack/datasync-filesystem-sdk", - "version": "1.1.0", + "version": "1.2.0", "license": "MIT", "dependencies": { "json-mask": "2.0.0", diff --git a/package.json b/package.json index b9ec898d..b4c2c1b2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@contentstack/datasync-filesystem-sdk", - "version": "1.1.0", + "version": "1.2.0", "description": "JavaScript filesystem SDK to query data synced via @contentstack/datasync-content-store-filesystem", "main": "dist/index.js", "scripts": { diff --git a/src/stack.ts b/src/stack.ts index 295f3c3e..5e83f6f2 100755 --- a/src/stack.ts +++ b/src/stack.ts @@ -1090,10 +1090,10 @@ export class Stack { } else if (this.q.includeSpecificReferences) { await this .includeSpecificReferences(data, this.q.content_type_uid, locale, this.q - .includeSpecificReferences) + .includeSpecificReferences, true) } else if (this.q.includeAllReferences) { // need re-writes - await this.bindReferences(data, this.q.content_type_uid, locale) + await this.bindReferences(data, this.q.content_type_uid, locale, false) } else { await this.includeAssetsOnly(data, locale, this.q.content_type_uid) @@ -1292,7 +1292,7 @@ export class Stack { return { output } } - private async includeSpecificReferences(entries: any[], contentTypeUid: string, locale: string, include: string[]) { + private async includeSpecificReferences(entries: any[], contentTypeUid: string, locale: string, include: string[], preserveUnpublished = false) { const ctQuery = { _content_type_uid: this.types.content_types, uid: contentTypeUid, @@ -1324,13 +1324,12 @@ export class Stack { // else, self-recursively iterate and fetch references // Note: Shelf is the one holding `pointers` to the actual entry // Once the pointer has been used, for GC, point the object to null - await this.includeReferenceIteration(queries, schemaList, locale, pendingPath, shelf) + await this.includeReferenceIteration(queries, schemaList, locale, pendingPath, shelf, preserveUnpublished) return } - private async includeReferenceIteration(eQuery: any, ctQuery: any, locale: string, include: string[], oldShelf: - IShelf[]) { + private async includeReferenceIteration(eQuery: any, ctQuery: any, locale: string, include: string[], oldShelf: IShelf[], preserveUnpublished = false) { if (oldShelf.length === 0) { return } else if (ctQuery.$or.length === 0 && eQuery.$or.length > 0) { @@ -1370,12 +1369,18 @@ export class Stack { if (flag) { for (let e = 0, f = oldShelf[i].path.length; e < f; e++) { - // tslint:disable-next-line: max-line-length if ( oldShelf[i].path[e]?.hasOwnProperty("_content_type_uid") && Object.keys(oldShelf[i].path[e]).length === 2 ) { - (oldShelf[i].path as any).splice(e, 1); + const ref = oldShelf[i].path[e]; + if (preserveUnpublished) { + ((oldShelf[i].path as any) as any[])[e] = typeof ref === "string" + ? { uid: ref, _content_type_uid: null } + : { uid: (ref as any).uid, _content_type_uid: (ref as any)._content_type_uid }; + } else { + ((oldShelf[i].path as any) as any[]).splice(e, 1); + } break; } } @@ -1387,7 +1392,7 @@ export class Stack { result = null // Iterative loops, that traverses paths and binds them onto entries - await this.includeReferenceIteration(queries, schemaList, locale, pendingPath, shelf) + await this.includeReferenceIteration(queries, schemaList, locale, pendingPath, shelf, preserveUnpublished) return } @@ -1667,7 +1672,7 @@ export class Stack { return } - private async bindReferences(entries: any[], contentTypeUid: string, locale: string) { + private async bindReferences(entries: any[], contentTypeUid: string, locale: string, preserveUnpublished = false) { const ctQuery: IQuery = { $or: [{ _content_type_uid: this.types.content_types, @@ -1699,7 +1704,7 @@ export class Stack { // Note: Shelf is the one holding `pointers` to the actual entry // Once the pointer has been used, for GC, point the object to null - return this.includeAllReferencesIteration(queries, ctQueries, locale, objectPointerList) + return this.includeAllReferencesIteration(queries, ctQueries, locale, objectPointerList, 0, preserveUnpublished) } private async bindLeftoverAssets(queries: IQuery, locale: string, pointerList: IShelf[]) { @@ -1727,7 +1732,7 @@ export class Stack { } // tslint:disable-next-line: max-line-length - private async includeAllReferencesIteration(oldEntryQueries: IQuery, oldCtQueries: IQuery, locale: string, oldObjectPointerList: IShelf[], depth = 0) { + private async includeAllReferencesIteration(oldEntryQueries: IQuery, oldCtQueries: IQuery, locale: string, oldObjectPointerList: IShelf[], depth = 0, preserveUnpublished = false) { if (depth > this.q.referenceDepth || oldObjectPointerList.length === 0) { return } else if (oldCtQueries.$or.length === 0 && oldObjectPointerList.length > 0 && oldEntryQueries.$or.length > 0) { @@ -1767,10 +1772,16 @@ export class Stack { if (flag) { for (let e = 0, f = oldObjectPointerList[i].path.length; e < f; e++) { - // tslint:disable-next-line: max-line-length if (oldObjectPointerList[i].path[e]?.hasOwnProperty('_content_type_uid') && Object.keys(oldObjectPointerList[i].path[e]).length === 2) { - (oldObjectPointerList[i].path as any).splice(e, 1) - break + const ref = oldObjectPointerList[i].path[e]; + if (preserveUnpublished) { + ((oldObjectPointerList[i].path as any) as any[])[e] = typeof ref === "string" + ? { uid: ref, _content_type_uid: null } + : { uid: (ref as any).uid, _content_type_uid: (ref as any)._content_type_uid }; + } else { + ((oldObjectPointerList[i].path as any) as any[]).splice(e, 1); + } + break; } } } @@ -1781,7 +1792,7 @@ export class Stack { ++depth // Iterative loops, that traverses paths and binds them onto entries - await this.includeAllReferencesIteration(queries, ctQueries, locale, shelf, depth) + await this.includeAllReferencesIteration(queries, ctQueries, locale, shelf, depth, preserveUnpublished) return }