├── .eslintignore ├── .eslintrc.js ├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md ├── dependabot.yaml └── workflows │ └── check.yaml ├── .gitignore ├── .huskyrc.js ├── .npmignore ├── .prettierrc.js ├── .vscode └── launch.json ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── PULL_REQUEST_TEMPLATE.md ├── apps ├── dev.to │ ├── README.md │ ├── package-lock.json │ ├── package.json │ ├── src │ │ ├── index.ts │ │ └── types.ts │ └── tsconfig.json ├── markdown-desktop │ ├── README.md │ ├── package.json │ ├── src │ │ ├── index.ts │ │ └── types.ts │ ├── tsconfig.json │ └── utils │ │ └── index.ts ├── markdown-native │ ├── README.md │ ├── package.json │ └── src │ │ ├── index.ts │ │ └── types.ts ├── markdown-vscode │ ├── README.md │ ├── package.json │ ├── src │ │ ├── index.ts │ │ └── types.ts │ ├── tsconfig.json │ └── utils │ │ └── index.ts ├── markdown-web │ ├── README.md │ ├── package.json │ ├── src │ │ ├── index.ts │ │ └── types.ts │ ├── tsconfig.json │ └── utils │ │ └── index.ts ├── notion-formula-web │ ├── README.md │ ├── package.json │ ├── src │ │ ├── index.ts │ │ └── types.ts │ ├── tsconfig.json │ └── utils │ │ └── index.ts └── publish │ ├── client │ ├── README.md │ ├── package-lock.json │ ├── package.json │ ├── public │ │ ├── index.css │ │ └── index.html │ ├── snowpack.config.js │ ├── src │ │ ├── components │ │ │ ├── App.css │ │ │ ├── App.tsx │ │ │ ├── PackageList │ │ │ │ ├── index.css │ │ │ │ └── index.tsx │ │ │ └── PackageStatus │ │ │ │ ├── index.css │ │ │ │ └── index.tsx │ │ ├── index.tsx │ │ └── utils │ │ │ ├── createPackagePublishOrder.ts │ │ │ ├── getPackages.ts │ │ │ └── publishPackages.ts │ └── tsconfig.json │ └── server │ ├── index.ts │ ├── package-lock.json │ ├── package.json │ └── tsconfig.json ├── docs ├── .gitignore ├── babel.config.js ├── docgen.js ├── docs │ ├── core │ │ └── Introduction │ │ │ └── Introduction.md │ ├── endpoints │ │ ├── Architecture │ │ │ └── Cache.md │ │ └── Introduction │ │ │ ├── Feature.md │ │ │ └── Introduction.md │ ├── markdown │ │ └── Introduction │ │ │ └── Introduction.md │ ├── notion-formula │ │ ├── Introduction │ │ │ ├── Features.md │ │ │ ├── Getting Started.md │ │ │ ├── Introduction.md │ │ │ └── Typescript Support.md │ │ ├── Parsing │ │ │ └── Errors.mdx │ │ ├── Reference │ │ │ └── Notion Functions.md │ │ ├── Theory │ │ │ ├── Notion Formula.md │ │ │ └── Schema Map.mdx │ │ └── Usage │ │ │ ├── Array Representation.md │ │ │ ├── Integration.mdx │ │ │ ├── Object Representation.md │ │ │ └── String Representation.md │ ├── root │ │ └── Introduction │ │ │ ├── Architecture.md │ │ │ ├── Features.md │ │ │ ├── Getting Started.md │ │ │ ├── Understanding Nishan.mdx │ │ │ └── Understanding Notion.mdx │ ├── sync │ │ └── Introduction │ │ │ └── Introduction.md │ ├── types │ │ └── Introduction │ │ │ └── Introduction.md │ └── utils │ │ ├── Introduction │ │ ├── Features.md │ │ ├── Getting Started.md │ │ └── Introduction.md │ │ └── Modules │ │ ├── InlineBlocks.md │ │ ├── generateSchemaMap.md │ │ └── uuidConversion.md ├── docusaurus.config.js ├── package-lock.json ├── package.json ├── scripts │ └── generateNotionFunctionReference.js ├── sidebars.js ├── src │ ├── css │ │ ├── custom.css │ │ └── tailwind.css │ ├── pages │ │ ├── index.js │ │ └── styles.module.css │ └── theme │ │ ├── AnnouncementBar │ │ ├── index.js │ │ └── styles.module.css │ │ ├── DocSidebar │ │ ├── index.js │ │ └── styles.module.css │ │ ├── NavbarItem │ │ ├── DefaultNavbarItem.js │ │ ├── DocNavbarItem.js │ │ ├── DocsVersionDropdownNavbarItem.js │ │ ├── DocsVersionNavbarItem.js │ │ ├── LocaleDropdownNavbarItem.js │ │ ├── index.js │ │ └── styles.module.css │ │ ├── TOC │ │ ├── index.js │ │ └── styles.module.css │ │ └── Toggle │ │ ├── index.js │ │ └── styles.module.css ├── static │ ├── .nojekyll │ └── img │ │ ├── cli │ │ ├── logo.svg │ │ └── logo_standalone.svg │ │ ├── core │ │ ├── logo.svg │ │ └── logo_standalone.svg │ │ ├── endpoints │ │ ├── logo.svg │ │ └── logo_standalone.svg │ │ ├── graphql │ │ ├── logo.svg │ │ └── logo_standalone.svg │ │ ├── logos │ │ ├── discord_dark_24.png │ │ ├── discord_light_24.png │ │ ├── github_dark_24.png │ │ ├── github_light_24.png │ │ ├── npm_dark_24.png │ │ └── npm_light_24.png │ │ ├── markdown │ │ ├── logo.svg │ │ └── logo_standalone.svg │ │ ├── notion-formula │ │ ├── logo.svg │ │ └── logo_standalone.svg │ │ ├── root │ │ ├── Logo@175px.png │ │ ├── Logo@350px.png │ │ ├── easy.svg │ │ ├── logo.svg │ │ ├── logo@100.svg │ │ ├── logo@88px.png │ │ ├── moon.svg │ │ ├── multi_purpose.svg │ │ ├── sun.svg │ │ └── ts_support.svg │ │ ├── sync │ │ ├── logo.svg │ │ └── logo_standalone.svg │ │ ├── types │ │ ├── logo.svg │ │ └── logo_standalone.svg │ │ └── utils │ │ ├── inlineblocks │ │ ├── text_bold_extra_italic.png │ │ ├── text_extra.png │ │ └── text_red_bg_extra_blue_bold.png │ │ ├── logo.svg │ │ └── logo_standalone.svg └── tailwind.config.js ├── jest.config.js ├── lerna.json ├── package.json ├── packages ├── cache │ ├── README.md │ ├── libs │ │ ├── constructAndSyncRecordsParams.ts │ │ ├── constructSyncRecordsParams.ts │ │ ├── createDefaultCache.ts │ │ ├── createDefaultCacheInitializeTracker.ts │ │ ├── extractNotionUserIds.ts │ │ ├── extractSpaceAndParentId.ts │ │ ├── fetchDataOrReturnCached.ts │ │ ├── fetchMultipleDataOrReturnCached.ts │ │ ├── index.ts │ │ ├── initializeCacheForSpecificData.ts │ │ ├── initializeNotionCache.ts │ │ ├── returnNonCachedData.ts │ │ ├── saveToCache.ts │ │ ├── types.ts │ │ ├── updateCacheIfNotPresent.ts │ │ ├── updateCacheManually.ts │ │ └── validateCache.ts │ ├── package.json │ ├── tests │ │ ├── constructAndSyncRecordsParams.test.ts │ │ ├── constructSyncRecordsParams.test.ts │ │ ├── createDefaultCache.test.ts │ │ ├── extractNotionUserIds.test.ts │ │ ├── extractSpaceAndParentId.test.ts │ │ ├── fetchDataOrReturnCached.test.ts │ │ ├── fetchMultipleDataOrReturnCached.test.ts │ │ ├── initializeCacheForSpecificData.test.ts │ │ ├── initializeNotionCache.test.ts │ │ ├── returnNonCachedData.test.ts │ │ ├── saveToCache.test.ts │ │ ├── updateCacheIfNotPresent.test.ts │ │ ├── updateCacheManually.test.ts │ │ └── validateCache.test.ts │ └── tsconfig.json ├── cli │ ├── README.md │ ├── libs │ │ ├── Page.ts │ │ ├── index.ts │ │ ├── types.ts │ │ └── utils │ │ │ ├── index.ts │ │ │ └── setIdentifierPositionalArgs.ts │ ├── package.json │ └── tsconfig.json ├── cms │ ├── libs │ │ └── index.ts │ ├── package.json │ ├── readme.md │ ├── tests │ │ └── index.test.ts │ └── tsconfig.json ├── constants │ ├── README.md │ ├── libs │ │ ├── bgColorTypes.ts │ │ ├── blockTypes.ts │ │ ├── colorTypes.ts │ │ ├── dataTypes.ts │ │ ├── functionNames.ts │ │ ├── index.ts │ │ ├── operationCommands.ts │ │ ├── schemaUnitTypes.ts │ │ └── viewTypes.ts │ ├── package.json │ ├── tests │ │ ├── bgColorTypes.test.ts │ │ ├── blockTypes.test.ts │ │ ├── colorTypes.test.ts │ │ ├── dataTypes.test.ts │ │ ├── functionNames.test.ts │ │ ├── operationCommands.test.ts │ │ ├── schemaUnitTypes.test.ts │ │ └── viewTypes.test.ts │ └── tsconfig.json ├── core │ ├── README.md │ ├── examples │ │ ├── README.md │ │ └── Workflow 1 │ │ │ ├── README.md │ │ │ ├── data │ │ │ ├── category.ts │ │ │ ├── difficulty.ts │ │ │ ├── ecosystem.ts │ │ │ ├── index.ts │ │ │ ├── phase.ts │ │ │ ├── priority.ts │ │ │ ├── purpose.ts │ │ │ ├── source.ts │ │ │ ├── status.ts │ │ │ ├── subject.ts │ │ │ └── utils.ts │ │ │ ├── index.ts │ │ │ ├── step_1 │ │ │ ├── index.ts │ │ │ └── readme.md │ │ │ ├── step_2 │ │ │ ├── README.md │ │ │ └── index.ts │ │ │ ├── step_3 │ │ │ ├── index.ts │ │ │ └── readme.md │ │ │ ├── step_4 │ │ │ ├── index.ts │ │ │ └── readme.md │ │ │ └── util.ts │ ├── libs │ │ ├── Api │ │ │ ├── Block │ │ │ │ ├── Block.ts │ │ │ │ ├── CollectionBlock.ts │ │ │ │ ├── CollectionView.ts │ │ │ │ ├── CollectionViewPage.ts │ │ │ │ ├── Page.ts │ │ │ │ ├── PageBlock.ts │ │ │ │ └── index.ts │ │ │ ├── Collection.ts │ │ │ ├── Comment.ts │ │ │ ├── Data.ts │ │ │ ├── Discussion.ts │ │ │ ├── Nishan.ts │ │ │ ├── NotionUser.ts │ │ │ ├── SchemaUnit.ts │ │ │ ├── Space.ts │ │ │ ├── SpaceView.ts │ │ │ ├── UserRoot.ts │ │ │ ├── UserSettings.ts │ │ │ ├── View │ │ │ │ ├── Aggregator.ts │ │ │ │ ├── BoardView.ts │ │ │ │ ├── CalendarView.ts │ │ │ │ ├── GalleryView.ts │ │ │ │ ├── ListView.ts │ │ │ │ ├── TableView.ts │ │ │ │ ├── TimelineView.ts │ │ │ │ ├── View.ts │ │ │ │ └── index.ts │ │ │ └── index.ts │ │ ├── CreateMaps │ │ │ ├── createBlockMap.ts │ │ │ ├── createPageMap.ts │ │ │ ├── createSchemaUnitMap.ts │ │ │ ├── createViewMap.ts │ │ │ └── index.ts │ │ ├── PopulateMap │ │ │ ├── index.ts │ │ │ ├── populateBlockMap.ts │ │ │ ├── populateCollectionBlockMap.ts │ │ │ ├── populatePageMap.ts │ │ │ ├── populateSchemaUnitMap.ts │ │ │ └── populateViewMap.ts │ │ ├── createBlockClass.ts │ │ ├── index.ts │ │ └── utils │ │ │ ├── applyMixins.ts │ │ │ ├── createSpaceIterateData.ts │ │ │ ├── index.ts │ │ │ └── transformToMultiple.ts │ ├── package.json │ ├── tests │ │ ├── Api │ │ │ ├── Block │ │ │ │ ├── Block.test.ts │ │ │ │ ├── CollectionBlock.test.ts │ │ │ │ ├── CollectionView.test.ts │ │ │ │ ├── CollectionViewPage.test.ts │ │ │ │ ├── Page.test.ts │ │ │ │ └── PageBlock.test.ts │ │ │ ├── Collection.test.ts │ │ │ ├── Data.test.ts │ │ │ ├── Discussion.test.ts │ │ │ ├── Nishan.test.ts │ │ │ ├── NotionUser.test.ts │ │ │ ├── SchemaUnit.test.ts │ │ │ ├── Space.test.ts │ │ │ ├── SpaceView.test.ts │ │ │ ├── UserRoot.test.ts │ │ │ └── View │ │ │ │ ├── Aggregator.test.ts │ │ │ │ ├── BoardView.test.ts │ │ │ │ ├── CalendarView.test.ts │ │ │ │ ├── GalleryView.test.ts │ │ │ │ ├── ListView.test.ts │ │ │ │ ├── TableView.test.ts │ │ │ │ ├── TimelineView.test.ts │ │ │ │ ├── View.test.ts │ │ │ │ └── utils.ts │ │ ├── CreateMaps │ │ │ ├── createBlockMap.test.ts │ │ │ ├── createPageMap.test.ts │ │ │ ├── createSchemaUnitMap.test.ts │ │ │ └── createViewMap.test.ts │ │ ├── PopulateMap │ │ │ ├── populateBlockMap.test.ts │ │ │ ├── populateCollectionBlockMap.test.ts │ │ │ ├── populatePageMap.test.ts │ │ │ ├── populateSchemaUnitMap.test.ts │ │ │ └── populateViewMap.test.ts │ │ ├── createBlockClass.test.ts │ │ ├── utils.ts │ │ └── utils │ │ │ └── transformToMultiple.test.ts │ ├── tsconfig.json │ └── types │ │ ├── block.ts │ │ ├── index.ts │ │ ├── maps.ts │ │ └── nishan.ts ├── discord-bot │ ├── README.md │ ├── package.json │ ├── src │ │ ├── index.ts │ │ └── types.ts │ ├── tsconfig.json │ └── utils │ │ └── index.ts ├── discourse │ ├── libs │ │ ├── Comments │ │ │ ├── createComments.ts │ │ │ ├── deleteComments.ts │ │ │ ├── getComments.ts │ │ │ ├── index.ts │ │ │ └── updateComments.ts │ │ ├── Discussions │ │ │ ├── createDiscussions.ts │ │ │ ├── deleteDiscussions.ts │ │ │ ├── getDiscussions.ts │ │ │ ├── index.ts │ │ │ └── updateDiscussions.ts │ │ ├── index.ts │ │ └── types.ts │ ├── package.json │ ├── readme.md │ ├── tests │ │ ├── Comments │ │ │ ├── createComments.test.ts │ │ │ ├── deleteComments.test.ts │ │ │ ├── getComments.test.ts │ │ │ └── updateComments.test.ts │ │ └── Discussions │ │ │ ├── createDiscussions.test.ts │ │ │ ├── deleteDiscussions.test.ts │ │ │ ├── getDiscussions.test.ts │ │ │ └── updateDiscussions.test.ts │ └── tsconfig.json ├── endpoints │ ├── README.md │ ├── libs │ │ ├── Mutations.ts │ │ ├── Queries.ts │ │ ├── Request │ │ │ ├── constructNotionHeaders.ts │ │ │ ├── createTransaction.ts │ │ │ ├── index.ts │ │ │ └── sendRequest.ts │ │ ├── index.ts │ │ └── types.ts │ ├── package.json │ ├── tests │ │ ├── Mutations.test.ts │ │ ├── Queries.test.ts │ │ └── Request │ │ │ ├── constructNotionHeader.test.ts │ │ │ ├── createTransaction.test.ts │ │ │ ├── sendRequest.test.ts │ │ │ └── utils.ts │ └── tsconfig.json ├── errors │ ├── README.md │ ├── libs │ │ ├── ChildIndexOutOfBound.ts │ │ ├── FunctionArgumentLengthMismatch.ts │ │ ├── FunctionArgumentTypeMismatch.ts │ │ ├── NonExistentData.ts │ │ ├── NonExistentSchemaUnitType.ts │ │ ├── PreExistentValue.ts │ │ ├── SchemaDuplicatePropertyName.ts │ │ ├── UnknownPropertyReference.ts │ │ ├── UnsupportedBlockType.ts │ │ ├── UnsupportedDataType.ts │ │ ├── UnsupportedFunctionName.ts │ │ ├── UnsupportedPropertyType.ts │ │ └── index.ts │ ├── package.json │ ├── tests │ │ ├── ChildIndexOutofBoundError.test.ts │ │ ├── FunctionArgumentLengthMismatch.test.ts │ │ ├── FunctionArgumentTypeMismatch.test.ts │ │ ├── NonExistentDataError.test.ts │ │ ├── NonExistentSchemaUnitTypeError.test.ts │ │ ├── PreExistentValueError.test.ts │ │ ├── SchemaDuplicatePropertyNameError.test.ts │ │ ├── UnknownPropertyReferenceError.test.ts │ │ ├── UnsupportedBlockTypeError.test.ts │ │ ├── UnsupportedDataTypeError.test.ts │ │ ├── UnsupportedFunctionName.test.ts │ │ └── UnsupportedPropertyTypeError.test.ts │ └── tsconfig.json ├── extract │ ├── libs │ │ ├── collection.ts │ │ ├── index.ts │ │ ├── pages.ts │ │ ├── types.ts │ │ └── views.ts │ ├── package.json │ ├── readme.md │ ├── tests │ │ ├── collection.test.ts │ │ ├── pages.test.ts │ │ └── views.test.ts │ └── tsconfig.json ├── fabricator │ ├── README.md │ ├── libs │ │ ├── CreateData │ │ │ ├── SchemaUnit │ │ │ │ ├── index.ts │ │ │ │ ├── relation.ts │ │ │ │ └── rollup.ts │ │ │ ├── collection.ts │ │ │ ├── contents.ts │ │ │ ├── index.ts │ │ │ ├── schema.ts │ │ │ ├── utils │ │ │ │ ├── executeOperationAndStoreInCache.ts │ │ │ │ ├── generateViewData.ts │ │ │ │ ├── index.ts │ │ │ │ └── populatePermissions.ts │ │ │ └── views.ts │ │ ├── PopulateViewData │ │ │ ├── format │ │ │ │ ├── format.ts │ │ │ │ ├── index.ts │ │ │ │ ├── properties.ts │ │ │ │ └── utils │ │ │ │ │ ├── index.ts │ │ │ │ │ └── tableFormat.ts │ │ │ ├── index.ts │ │ │ └── query2 │ │ │ │ ├── aggregation.ts │ │ │ │ ├── filters.ts │ │ │ │ ├── index.ts │ │ │ │ ├── query2.ts │ │ │ │ └── sort.ts │ │ ├── PopulateViewMaps │ │ │ ├── aggregations.ts │ │ │ ├── filters.ts │ │ │ ├── index.ts │ │ │ ├── properties.ts │ │ │ └── sorts.ts │ │ └── index.ts │ ├── package.json │ ├── tests │ │ ├── CreateData │ │ │ ├── SchemaUnit │ │ │ │ ├── relation.test.ts │ │ │ │ └── rollup.test.ts │ │ │ ├── collection.test.ts │ │ │ ├── contents.test.ts │ │ │ ├── schema.test.ts │ │ │ ├── utils │ │ │ │ ├── executeOperationAndStoreInCache.test.ts │ │ │ │ └── generateViewData.test.ts │ │ │ └── views.test.ts │ │ ├── PopulateViewData │ │ │ ├── format │ │ │ │ ├── format.test.ts │ │ │ │ └── properties.test.ts │ │ │ └── query2 │ │ │ │ ├── aggregation.test.ts │ │ │ │ ├── filters.test.ts │ │ │ │ ├── query2.test.ts │ │ │ │ └── sort.test.ts │ │ ├── PopulateViewMaps │ │ │ ├── aggregations.test.ts │ │ │ ├── filters.test.ts │ │ │ ├── properties.test.ts │ │ │ ├── sorts.test.ts │ │ │ └── utils.ts │ │ └── utils.ts │ ├── tsconfig.json │ └── types │ │ ├── aggregations.ts │ │ ├── block.ts │ │ ├── filter.ts │ │ ├── index.ts │ │ ├── schema.ts │ │ ├── sort.ts │ │ ├── utils.ts │ │ └── view.ts ├── graphql │ ├── README.md │ ├── libs │ │ ├── Resolvers │ │ │ ├── collection.ts │ │ │ ├── collection_block.ts │ │ │ ├── index.ts │ │ │ ├── page.ts │ │ │ ├── query.ts │ │ │ ├── space.ts │ │ │ └── utils │ │ │ │ ├── commonBlockResolvers.ts │ │ │ │ ├── getBlockResolveType.ts │ │ │ │ ├── getParentResolveType.ts │ │ │ │ ├── index.ts │ │ │ │ └── notionUserResolvers.ts │ │ ├── index.ts │ │ ├── server.ts │ │ ├── typedefs.ts │ │ └── utils │ │ │ ├── index.ts │ │ │ └── initializeNishan.ts │ ├── package.json │ ├── tests │ │ ├── Resolvers │ │ │ ├── collection.test.ts │ │ │ ├── collection_block.test.ts │ │ │ ├── page.test.ts │ │ │ ├── query.test.ts │ │ │ ├── space.test.ts │ │ │ └── utils │ │ │ │ ├── CommonBlockResolvers.test.ts │ │ │ │ ├── NotionUserResolvers.test.ts │ │ │ │ ├── getBlockResolveType.test.ts │ │ │ │ └── getParentResolveType.test.ts │ │ ├── server.test.ts │ │ └── utils │ │ │ └── initializeNishan.test.ts │ └── tsconfig.json ├── idz │ ├── README.md │ ├── libs │ │ ├── Generate │ │ │ ├── generateId.ts │ │ │ ├── generateShortId.ts │ │ │ └── index.ts │ │ ├── Transform │ │ │ ├── index.ts │ │ │ ├── transformToId.ts │ │ │ └── transformToUuid.ts │ │ ├── Validate │ │ │ ├── index.ts │ │ │ ├── validateId.ts │ │ │ └── validateUuid.ts │ │ └── index.ts │ ├── package.json │ ├── tests │ │ ├── Generate │ │ │ ├── generateId.test.ts │ │ │ └── generateShortId.test.ts │ │ ├── Transform │ │ │ ├── toId.test.ts │ │ │ └── toUuid.test.ts │ │ └── Validate │ │ │ ├── validateId.test.ts │ │ │ └── validateUuid.test.ts │ └── tsconfig.json ├── init │ ├── libs │ │ ├── View │ │ │ ├── aggregation.ts │ │ │ ├── filter.ts │ │ │ ├── index.ts │ │ │ └── sort.ts │ │ ├── blockMetadata.ts │ │ ├── collection.ts │ │ ├── comment.ts │ │ ├── discussion.ts │ │ ├── index.ts │ │ └── spaceView.ts │ ├── package.json │ ├── readme.md │ ├── tests │ │ ├── View │ │ │ ├── aggregation.test.ts │ │ │ ├── filter.test.ts │ │ │ └── sort.test.ts │ │ ├── blockMetadata.test.ts │ │ ├── collection.test.ts │ │ ├── comment.test.ts │ │ ├── discussion.test.ts │ │ └── spaceView.test.ts │ └── tsconfig.json ├── inline-blocks │ ├── README.md │ ├── libs │ │ ├── NotionInlineBlock.ts │ │ ├── TextHighlightColor.ts │ │ ├── TextStyleFormatter.ts │ │ ├── index.ts │ │ └── types.ts │ ├── package.json │ ├── tests │ │ ├── NotionInlineBlock.test.ts │ │ ├── TextHighlightColor.test.ts │ │ └── TextStyleFormat.test.ts │ └── tsconfig.json ├── lineage │ ├── libs │ │ ├── Block │ │ │ ├── getCommentIds.ts │ │ │ └── index.ts │ │ ├── Collection │ │ │ ├── getRowPageIds.ts │ │ │ └── index.ts │ │ ├── NotionUser │ │ │ ├── getSpaceIds.ts │ │ │ └── index.ts │ │ ├── Page │ │ │ ├── getCommentIds.ts │ │ │ ├── getDiscussionIds.ts │ │ │ ├── getFollowId.ts │ │ │ └── index.ts │ │ ├── Space │ │ │ ├── getSpaceView.ts │ │ │ └── index.ts │ │ ├── getPageIds.ts │ │ ├── index.ts │ │ ├── positionChildren.ts │ │ ├── types.ts │ │ └── updateChildContainer.ts │ ├── package.json │ ├── readme.md │ ├── tests │ │ ├── Block │ │ │ └── getCommentIds.test.ts │ │ ├── Collection │ │ │ └── getRowPageIds.test.ts │ │ ├── NotionUser │ │ │ └── getSpaceIds.test.ts │ │ ├── Page │ │ │ ├── getCommentIds.test.ts │ │ │ ├── getDiscussionIds.test.ts │ │ │ └── getFollowId.test.ts │ │ ├── Space │ │ │ └── getSpaceView.test.ts │ │ ├── getPageIds.test.ts │ │ ├── positionChildren.test.ts │ │ └── updateChildContainer.test.ts │ └── tsconfig.json ├── logger │ ├── README.md │ ├── libs │ │ ├── endpointLogger.ts │ │ ├── errorLogger.ts │ │ ├── index.ts │ │ └── methodLogger.ts │ ├── package.json │ ├── tests │ │ ├── endpointLogger.test.ts │ │ ├── errorLogger.test.ts │ │ └── methodLogger.test.ts │ └── tsconfig.json ├── markdown │ ├── README.md │ ├── examples │ │ └── example.md │ ├── package.json │ ├── src │ │ ├── index.ts │ │ ├── types.ts │ │ └── uploadMarkdown.ts │ ├── tsconfig.json │ └── utils │ │ ├── convertFrontMatter2Obj.ts │ │ ├── createTransactions.ts │ │ ├── getNotionData.ts │ │ ├── index.ts │ │ ├── mdast2NotionBlocks.ts │ │ ├── notionBlocks2Operations.ts │ │ ├── parseFile.ts │ │ ├── parseListNode.ts │ │ ├── parseNodes.ts │ │ ├── parseParagraphNode.ts │ │ └── uploadToNotion.ts ├── notion-formula │ ├── README.md │ ├── libs │ │ ├── FunctionFormulaInfo │ │ │ ├── array.ts │ │ │ ├── index.ts │ │ │ ├── map.ts │ │ │ ├── types.ts │ │ │ └── utils │ │ │ │ ├── generateFormulaInfo.ts │ │ │ │ └── index.ts │ │ ├── GenerateAST │ │ │ ├── array.ts │ │ │ ├── index.ts │ │ │ ├── object.ts │ │ │ ├── string.ts │ │ │ └── utils │ │ │ │ ├── generateNotionFormulaAST.ts │ │ │ │ ├── getResultTypeFromSchemaType.ts │ │ │ │ └── index.ts │ │ ├── GenerateArg │ │ │ ├── index.ts │ │ │ ├── literal.ts │ │ │ └── property.ts │ │ ├── generateSchemaMapFromRemoteSchema.ts │ │ └── index.ts │ ├── package.json │ ├── tests │ │ ├── GenerateAST │ │ │ ├── array.test.ts │ │ │ ├── object.test.ts │ │ │ ├── string.test.ts │ │ │ └── utils │ │ │ │ ├── generateNotionFormulaAST.test.ts │ │ │ │ └── getResultTypeFromSchemaType.test.ts │ │ ├── GenerateArg │ │ │ ├── literal.test.ts │ │ │ └── property.test.ts │ │ ├── generateSchemaMapFromRemoteSchema.test.ts │ │ └── utils.ts │ ├── tsconfig.json │ └── types │ │ ├── formula-array.ts │ │ ├── formula-object.ts │ │ └── index.ts ├── operations │ ├── README.md │ ├── libs │ │ ├── Chunk │ │ │ └── index.ts │ │ ├── Plugins │ │ │ ├── Options │ │ │ │ ├── index.ts │ │ │ │ └── skip.ts │ │ │ ├── index.ts │ │ │ ├── removeEmptyOperationsPlugin.ts │ │ │ ├── removeLastEditedPropsPlugin.ts │ │ │ └── validateOperationsPlugin.ts │ │ ├── applyPluginsToOperationsStack.ts │ │ ├── executeOperations.ts │ │ ├── index.ts │ │ └── types.ts │ ├── package.json │ ├── tests │ │ ├── Chunk │ │ │ └── Operations.test.ts │ │ ├── Plugins │ │ │ ├── Options │ │ │ │ └── skipOption.test.ts │ │ │ ├── removeEmptyOperationsPlugin.test.ts │ │ │ ├── removeLastEditedPropsPlugin.test.ts │ │ │ └── validateOperationsPlugin.test.ts │ │ ├── applyPluginsToOperationsStack.test.ts │ │ ├── executeOperations.test.ts │ │ └── utils.ts │ └── tsconfig.json ├── orm │ ├── README.md │ ├── libs │ │ ├── Db │ │ │ ├── createDbs.ts │ │ │ ├── deleteDbs.ts │ │ │ ├── getTables.ts │ │ │ ├── index.ts │ │ │ └── updateDbs.ts │ │ ├── Table │ │ │ ├── createTables.ts │ │ │ ├── deleteTables.ts │ │ │ └── index.ts │ │ ├── index.ts │ │ └── types.ts │ ├── package.json │ └── tsconfig.json ├── permissions │ ├── README.md │ ├── libs │ │ ├── BlockPermissions.ts │ │ ├── SpacePermissions.ts │ │ └── index.ts │ ├── package.json │ ├── tests │ │ ├── BlockPermissions.test.ts │ │ └── SpacePermissions.test.ts │ └── tsconfig.json ├── react-filters │ ├── .env │ ├── .storybook │ │ ├── main.js │ │ └── preview.js │ ├── README.md │ ├── package.json │ ├── public │ │ └── index.html │ ├── src │ │ ├── NotionFilter.tsx │ │ ├── components │ │ │ ├── Filter │ │ │ │ └── Group │ │ │ │ │ ├── Add │ │ │ │ │ └── index.tsx │ │ │ │ │ ├── Item │ │ │ │ │ ├── Operator │ │ │ │ │ │ └── index.tsx │ │ │ │ │ ├── Options │ │ │ │ │ │ └── index.tsx │ │ │ │ │ ├── Property │ │ │ │ │ │ └── index.tsx │ │ │ │ │ ├── Value │ │ │ │ │ │ └── index.tsx │ │ │ │ │ └── index.tsx │ │ │ │ │ ├── Operator │ │ │ │ │ └── index.tsx │ │ │ │ │ ├── Options │ │ │ │ │ └── index.tsx │ │ │ │ │ └── index.tsx │ │ │ └── Shared │ │ │ │ ├── BasicAutocomplete │ │ │ │ └── index.tsx │ │ │ │ ├── BasicMenu │ │ │ │ └── index.tsx │ │ │ │ ├── BasicSelect │ │ │ │ └── index.tsx │ │ │ │ ├── Svgicon │ │ │ │ └── index.tsx │ │ │ │ ├── TagsAutocomplete │ │ │ │ └── index.tsx │ │ │ │ └── index.ts │ │ ├── globalTheme.ts │ │ ├── index.scss │ │ ├── index.tsx │ │ ├── react-app-env.d.ts │ │ ├── setupTests.ts │ │ ├── stories │ │ │ ├── Button.stories.tsx │ │ │ ├── Button.tsx │ │ │ ├── Header.stories.tsx │ │ │ ├── Header.tsx │ │ │ ├── Introduction.stories.mdx │ │ │ ├── Page.stories.tsx │ │ │ ├── Page.tsx │ │ │ ├── assets │ │ │ │ ├── code-brackets.svg │ │ │ │ ├── colors.svg │ │ │ │ ├── comments.svg │ │ │ │ ├── direction.svg │ │ │ │ ├── flow.svg │ │ │ │ ├── plugin.svg │ │ │ │ ├── repo.svg │ │ │ │ └── stackalt.svg │ │ │ ├── button.css │ │ │ ├── header.css │ │ │ └── page.css │ │ ├── types.ts │ │ └── utils │ │ │ ├── convertIntoSelectMenuItem.ts │ │ │ ├── createFilterLiterals.ts │ │ │ ├── getFilterInfoFromSchemaUnit.ts │ │ │ └── orderSchema.ts │ └── tsconfig.json ├── remark-notion │ ├── README.md │ ├── package.json │ ├── src │ │ ├── index.ts │ │ └── types.ts │ └── tsconfig.json ├── schema-builder │ ├── README.md │ ├── package.json │ ├── src │ │ ├── index.ts │ │ └── types.ts │ ├── tsconfig.json │ └── utils │ │ └── index.ts ├── sync │ ├── README.md │ ├── libs │ │ ├── Read │ │ │ ├── index.ts │ │ │ ├── readFromFile.ts │ │ │ ├── readFromMongodb.ts │ │ │ └── readFromNotion.ts │ │ ├── Restore │ │ │ ├── fromFile.ts │ │ │ ├── fromMongodb.ts │ │ │ └── index.ts │ │ ├── Store │ │ │ ├── File │ │ │ │ ├── fromMongodb.ts │ │ │ │ ├── fromNotion.ts │ │ │ │ └── index.ts │ │ │ ├── Mongodb │ │ │ │ ├── fromFile.ts │ │ │ │ ├── fromNotion.ts │ │ │ │ └── index.ts │ │ │ └── index.ts │ │ ├── Write │ │ │ ├── index.ts │ │ │ ├── writeToFile.ts │ │ │ ├── writeToMongodb.ts │ │ │ └── writeToNotion.ts │ │ ├── extractData.ts │ │ ├── index.ts │ │ └── types.ts │ ├── package.json │ ├── tests │ │ ├── Read │ │ │ ├── readFromFile.test.ts │ │ │ ├── readFromMongodb.test.ts │ │ │ └── readFromNotion.test.ts │ │ ├── Restore │ │ │ ├── fromFile.test.ts │ │ │ └── fromMongodb.test.ts │ │ ├── Store │ │ │ ├── File │ │ │ │ ├── fromMongodb.test.ts │ │ │ │ └── fromNotion.test.ts │ │ │ └── Mongodb │ │ │ │ ├── fromFile.test.ts │ │ │ │ └── fromNotion.test.ts │ │ ├── Write │ │ │ ├── writeToFile.test.ts │ │ │ ├── writeToMongodb.test.ts │ │ │ └── writeToNotion.test.ts │ │ └── extractData.test.ts │ └── tsconfig.json ├── tasks │ ├── libs │ │ ├── Export │ │ │ ├── exportBlock.ts │ │ │ ├── exportSpace.ts │ │ │ └── index.ts │ │ ├── enqueueAndPollTask.ts │ │ ├── importFile.ts │ │ └── index.ts │ ├── package.json │ ├── readme.md │ ├── tests │ │ ├── Export │ │ │ ├── exportBlock.test.ts │ │ │ └── exportSpace.test.ts │ │ ├── enqueueAndPollTask.test.ts │ │ └── importFile.test.ts │ └── tsconfig.json ├── traverser │ ├── libs │ │ ├── delete.ts │ │ ├── get.ts │ │ ├── index.ts │ │ ├── types.ts │ │ ├── update.ts │ │ └── utils │ │ │ ├── getChildIds.ts │ │ │ ├── index.ts │ │ │ └── iterateChildren.ts │ ├── package.json │ ├── readme.md │ ├── tests │ │ ├── delete.test.ts │ │ ├── get.test.ts │ │ ├── update.test.ts │ │ ├── utils.ts │ │ └── utils │ │ │ └── iterateChildren.test.ts │ └── tsconfig.json ├── typegen │ ├── README.md │ ├── libs │ │ ├── index.ts │ │ └── types.ts │ ├── package.json │ └── tsconfig.json ├── types │ ├── README.md │ ├── libs │ │ ├── activity.ts │ │ ├── aggregator.ts │ │ ├── block.ts │ │ ├── color.ts │ │ ├── credit.ts │ │ ├── date.ts │ │ ├── endpoints.ts │ │ ├── error.ts │ │ ├── filter.ts │ │ ├── formula.ts │ │ ├── index.ts │ │ ├── inlineformat.ts │ │ ├── notifications.ts │ │ ├── operation.ts │ │ ├── permissions.ts │ │ ├── recordMap.ts │ │ ├── schema.ts │ │ ├── search.ts │ │ ├── shared.ts │ │ ├── subscription.ts │ │ ├── tasks.ts │ │ ├── types.ts │ │ └── view.ts │ ├── package.json │ └── tsconfig.json ├── utils │ ├── README.md │ ├── libs │ │ ├── createDefaultRecordMap.ts │ │ ├── deepMerge.ts │ │ ├── extractInlineBlockContent.ts │ │ ├── generateSchemaMap.ts │ │ ├── getSchemaMapUnit.ts │ │ ├── getSchemaUnit.ts │ │ ├── index.ts │ │ ├── populateChildPath.ts │ │ ├── setDefault.ts │ │ ├── types.ts │ │ └── updateLastEditedProps.ts │ ├── package.json │ ├── tests │ │ ├── createDefaultRecordMap.test.ts │ │ ├── deepMerge.test.ts │ │ ├── extractInlineBlockContent.test.ts │ │ ├── getSchemaMapUnit.test.ts │ │ ├── getSchemaUnit.test.ts │ │ ├── populateChildPath.test.ts │ │ ├── setDefault.test.ts │ │ └── updateLastEditedProps.test.ts │ └── tsconfig.json └── validators │ ├── libs │ ├── checkDateSchemaUnit.ts │ ├── checkSelectSchemaUnit.ts │ ├── dataContainsAliveProp.ts │ ├── dataContainsEditedProps.ts │ └── index.ts │ ├── package.json │ ├── readme.md │ ├── tests │ ├── checkDateSchemaUnit.test.ts │ ├── checkSelectSchemaUnit.test.ts │ ├── dataContainsAliveProp.test.ts │ └── dataContainsEditedProps.test.ts │ └── tsconfig.json ├── readme.md ├── scripts ├── libs │ ├── Create │ │ ├── createDependencyMap.ts │ │ ├── createDependencyVersionMap.ts │ │ ├── createImportedPackagesSourceFile.ts │ │ ├── createPackageDirectory.ts │ │ ├── createPackageMap.ts │ │ ├── createPackagePublishOrder.ts │ │ ├── createPackagesData.ts │ │ ├── createReadme.ts │ │ └── index.ts │ ├── Extract │ │ ├── extractDependencies.ts │ │ ├── extractModuleDependencies.ts │ │ ├── extractPackageDependencies.ts │ │ ├── extractPackageInstalledDependencies.ts │ │ └── index.ts │ ├── Get │ │ ├── getOutdatedDeps.ts │ │ ├── getPackageJsonData.ts │ │ ├── getPackageJsonDependencies.ts │ │ ├── getPackageNonInstalledDependencies.ts │ │ ├── getPackagesNonInstalledDependencies.ts │ │ └── index.ts │ ├── Install │ │ ├── index.ts │ │ └── installLinkedDeps.ts │ ├── Link │ │ ├── index.ts │ │ └── linkPackages.ts │ ├── Publish │ │ ├── index.ts │ │ ├── publishAfterBuild.ts │ │ └── publishUpdatedPackages.ts │ ├── Test │ │ └── testImports.ts │ ├── Update │ │ ├── index.ts │ │ ├── updateOutdatedDeps.ts │ │ ├── updatePackageDependency.ts │ │ ├── updatePackageDescription.ts │ │ ├── updatePackageMetadata.ts │ │ └── updatePatchVersion.ts │ ├── index.ts │ ├── types.ts │ └── utils │ │ ├── index.ts │ │ ├── jsonReplacer.ts │ │ └── jsonReviver.ts ├── package-lock.json ├── package.json ├── packages.json ├── tsconfig.json └── uploadTestCoverageReports.sh ├── tsconfig.json ├── tsconfig.shared.json ├── utils └── tests │ ├── createDefaultNishanArg.ts │ ├── executeOperationsMock.ts │ └── index.ts └── yarn.lock /.eslintignore: -------------------------------------------------------------------------------- 1 | /docs/**/*.js 2 | /packages/markdown -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/dependabot.yaml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: npm 4 | directory: "/" 5 | schedule: 6 | interval: daily 7 | open-pull-requests-limit: 10 8 | labels: 9 | - dependency-update 10 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | **/node_modules 2 | **/feature.md 3 | **/dist 4 | **/build 5 | /docs/.docusaurus 6 | /test.ts 7 | .netlify 8 | /docs/build 9 | /scripts/data 10 | **/env.ts 11 | **/*.tgz 12 | **/experiment 13 | **/coverage 14 | .DS_Store 15 | **/*.eslintcache 16 | **/*.env 17 | docs/sidebars/ 18 | docs/**/api 19 | !docs/docs/Introduction -------------------------------------------------------------------------------- /.huskyrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | hooks: { 3 | 'pre-push': 'yarn run sort:packagejson && yarn test' 4 | } 5 | }; -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | # Node files 2 | package-lock.json 3 | **/*.tgz 4 | 5 | # source files 6 | **/*.ts 7 | !**/dist 8 | !**/*.d.ts 9 | **/src 10 | /workflows 11 | /.github -------------------------------------------------------------------------------- /.prettierrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | trailingComma: 'none', 3 | tabWidth: 2, 4 | semi: true, 5 | singleQuote: true 6 | } 7 | -------------------------------------------------------------------------------- /PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | * **Please check if the PR fulfills these requirements** 2 | - [ ] The commit message follows our guidelines 3 | - [ ] Tests for the changes have been added (for bug fixes / features) 4 | - [ ] Docs have been added / updated (for bug fixes / features) 5 | 6 | 7 | * **What kind of change does this PR introduce?** (Bug fix, feature, docs update, ...) 8 | 9 | 10 | 11 | * **What is the current behavior?** (You can also link to an open issue here) 12 | 13 | 14 | 15 | * **What is the new behavior (if this is a feature change)?** 16 | 17 | 18 | 19 | * **Does this PR introduce a breaking change?** (What changes might users need to make in their application due to this PR?) 20 | 21 | 22 | 23 | * **Other information**: 24 | -------------------------------------------------------------------------------- /apps/dev.to/README.md: -------------------------------------------------------------------------------- 1 | # Dev.to integration with Notion 2 | 3 | An app that allows you to collect your dev.to bookmarks and store them in a notion database with all the necessary data. -------------------------------------------------------------------------------- /apps/dev.to/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "dev.to", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.ts", 6 | "scripts": {}, 7 | "keywords": [], 8 | "dependencies": { 9 | "@nishans/fabricator": "0.0.30", 10 | "axios": "^0.21.1", 11 | "@nishans/cache": "0.0.35" 12 | }, 13 | "author": "Safwan Shaheer ", 14 | "license": "MIT" 15 | } -------------------------------------------------------------------------------- /apps/dev.to/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.shared.json", 3 | "include": [ 4 | "./src/index.ts", 5 | "./experiment" 6 | ], 7 | "compilerOptions": { 8 | "outDir": "./dist", 9 | "rootDir": "./" 10 | } 11 | } -------------------------------------------------------------------------------- /apps/markdown-desktop/README.md: -------------------------------------------------------------------------------- 1 | # `markdown-desktop` 2 | 3 | > TODO: description 4 | 5 | ## Usage 6 | 7 | ``` 8 | const markdownDesktop = require('markdown-desktop'); 9 | 10 | // TODO: DEMONSTRATE API 11 | ``` 12 | -------------------------------------------------------------------------------- /apps/markdown-desktop/src/index.ts: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = markdownDesktop; 4 | 5 | function markdownDesktop() { 6 | // TODO 7 | } 8 | -------------------------------------------------------------------------------- /apps/markdown-desktop/src/types.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Devorein/Nishan/5c258d07d6a5a9ea45a3b44ec04eb19018f4deda/apps/markdown-desktop/src/types.ts -------------------------------------------------------------------------------- /apps/markdown-desktop/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "lib": [ 4 | "ESNext", 5 | "dom", 6 | ], 7 | "baseUrl": "./", 8 | "module": "commonjs", 9 | "moduleResolution": "node", 10 | "target": "ES2015", 11 | "strict": true, 12 | "esModuleInterop": true, 13 | "skipLibCheck": true, 14 | "forceConsistentCasingInFileNames": true, 15 | "outDir": "./dist", 16 | "watch": false, 17 | "declaration": true, 18 | "sourceMap": false, 19 | "noUnusedLocals": false, 20 | "incremental": false 21 | }, 22 | "include": [ 23 | "./src/index.ts", 24 | "experiment" 25 | ], 26 | "exclude": [ 27 | "./node_modules", 28 | ] 29 | } -------------------------------------------------------------------------------- /apps/markdown-desktop/utils/index.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Devorein/Nishan/5c258d07d6a5a9ea45a3b44ec04eb19018f4deda/apps/markdown-desktop/utils/index.ts -------------------------------------------------------------------------------- /apps/markdown-native/README.md: -------------------------------------------------------------------------------- 1 | # `markdown-native` 2 | 3 | > TODO: description 4 | 5 | ## Usage 6 | 7 | ``` 8 | const markdownNative = require('markdown-native'); 9 | 10 | // TODO: DEMONSTRATE API 11 | ``` 12 | -------------------------------------------------------------------------------- /apps/markdown-native/src/index.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Devorein/Nishan/5c258d07d6a5a9ea45a3b44ec04eb19018f4deda/apps/markdown-native/src/index.ts -------------------------------------------------------------------------------- /apps/markdown-native/src/types.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Devorein/Nishan/5c258d07d6a5a9ea45a3b44ec04eb19018f4deda/apps/markdown-native/src/types.ts -------------------------------------------------------------------------------- /apps/markdown-vscode/README.md: -------------------------------------------------------------------------------- 1 | # `markdown-vscode` 2 | 3 | > TODO: description 4 | 5 | ## Usage 6 | 7 | ``` 8 | const markdownVscode = require('markdown-vscode'); 9 | 10 | // TODO: DEMONSTRATE API 11 | ``` 12 | -------------------------------------------------------------------------------- /apps/markdown-vscode/src/index.ts: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = markdownVscode; 4 | 5 | function markdownVscode() { 6 | // TODO 7 | } 8 | -------------------------------------------------------------------------------- /apps/markdown-vscode/src/types.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Devorein/Nishan/5c258d07d6a5a9ea45a3b44ec04eb19018f4deda/apps/markdown-vscode/src/types.ts -------------------------------------------------------------------------------- /apps/markdown-vscode/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "lib": [ 4 | "ESNext", 5 | "dom", 6 | ], 7 | "baseUrl": "./", 8 | "module": "commonjs", 9 | "moduleResolution": "node", 10 | "target": "ES2015", 11 | "strict": true, 12 | "esModuleInterop": true, 13 | "skipLibCheck": true, 14 | "forceConsistentCasingInFileNames": true, 15 | "outDir": "./dist", 16 | "watch": false, 17 | "declaration": true, 18 | "sourceMap": false, 19 | "noUnusedLocals": false, 20 | "incremental": false 21 | }, 22 | "include": [ 23 | "./src/index.ts", 24 | "experiment" 25 | ], 26 | "exclude": [ 27 | "./node_modules", 28 | ] 29 | } -------------------------------------------------------------------------------- /apps/markdown-vscode/utils/index.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Devorein/Nishan/5c258d07d6a5a9ea45a3b44ec04eb19018f4deda/apps/markdown-vscode/utils/index.ts -------------------------------------------------------------------------------- /apps/markdown-web/README.md: -------------------------------------------------------------------------------- 1 | # `markdown-web` 2 | 3 | > TODO: description 4 | 5 | ## Usage 6 | 7 | ``` 8 | const markdownWeb = require('markdown-web'); 9 | 10 | // TODO: DEMONSTRATE API 11 | ``` 12 | -------------------------------------------------------------------------------- /apps/markdown-web/src/index.ts: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = markdownWeb; 4 | 5 | function markdownWeb() { 6 | // TODO 7 | } 8 | -------------------------------------------------------------------------------- /apps/markdown-web/src/types.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Devorein/Nishan/5c258d07d6a5a9ea45a3b44ec04eb19018f4deda/apps/markdown-web/src/types.ts -------------------------------------------------------------------------------- /apps/markdown-web/utils/index.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Devorein/Nishan/5c258d07d6a5a9ea45a3b44ec04eb19018f4deda/apps/markdown-web/utils/index.ts -------------------------------------------------------------------------------- /apps/notion-formula-web/README.md: -------------------------------------------------------------------------------- 1 | # `markdown-web` 2 | 3 | > TODO: description 4 | 5 | ## Usage 6 | 7 | ``` 8 | const markdownWeb = require('markdown-web'); 9 | 10 | // TODO: DEMONSTRATE API 11 | ``` 12 | -------------------------------------------------------------------------------- /apps/notion-formula-web/src/index.ts: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = markdownWeb; 4 | 5 | function markdownWeb() { 6 | // TODO 7 | } 8 | -------------------------------------------------------------------------------- /apps/notion-formula-web/src/types.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Devorein/Nishan/5c258d07d6a5a9ea45a3b44ec04eb19018f4deda/apps/notion-formula-web/src/types.ts -------------------------------------------------------------------------------- /apps/notion-formula-web/utils/index.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Devorein/Nishan/5c258d07d6a5a9ea45a3b44ec04eb19018f4deda/apps/notion-formula-web/utils/index.ts -------------------------------------------------------------------------------- /apps/publish/client/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Devorein/Nishan/5c258d07d6a5a9ea45a3b44ec04eb19018f4deda/apps/publish/client/README.md -------------------------------------------------------------------------------- /apps/publish/client/public/index.css: -------------------------------------------------------------------------------- 1 | /* Add CSS styles here! */ 2 | body { 3 | font-family: sans-serif; 4 | } 5 | -------------------------------------------------------------------------------- /apps/publish/client/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Starter Snowpack App 10 | 11 | 12 | 13 |
14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /apps/publish/client/snowpack.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import("snowpack").SnowpackUserConfig } */ 2 | module.exports = { 3 | mount: { 4 | // directory name: 'build directory' 5 | public: '/', 6 | src: '/dist', 7 | }, 8 | plugins: ['@snowpack/plugin-react-refresh', '@snowpack/plugin-typescript'], 9 | routes: [], 10 | optimize: {}, 11 | packageOptions: {}, 12 | devOptions: {}, 13 | buildOptions: {}, 14 | }; 15 | -------------------------------------------------------------------------------- /apps/publish/client/src/components/App.css: -------------------------------------------------------------------------------- 1 | .App { 2 | display: grid; 3 | grid-template: 1fr 50px/1fr 2fr; 4 | height: 100vh; 5 | width: 100vw; 6 | overflow: hidden; 7 | } 8 | 9 | body{ 10 | margin: 0px; 11 | padding: 0px; 12 | } 13 | 14 | button{ 15 | background: black; 16 | outline: none; 17 | border: none; 18 | color: white; 19 | font-weight: bold; 20 | font-size: 1em; 21 | cursor: pointer; 22 | } 23 | 24 | -------------------------------------------------------------------------------- /apps/publish/client/src/components/PackageList/index.css: -------------------------------------------------------------------------------- 1 | .PackageList{ 2 | height: 100%; 3 | overflow: auto; 4 | background: #212121; 5 | } 6 | 7 | .PackageList-item{ 8 | padding: 3px; 9 | display: flex; 10 | user-select: none; 11 | color: white; 12 | } 13 | 14 | .PackageList-item-name { 15 | padding-left: 5px; 16 | } 17 | 18 | input.PackageList-item-checkbox { 19 | cursor: pointer; 20 | } -------------------------------------------------------------------------------- /apps/publish/client/src/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import App from './components/App.jsx'; 4 | 5 | ReactDOM.render( 6 | 7 | 8 | , 9 | document.getElementById('root'), 10 | ); 11 | 12 | if ((import.meta as any).hot) { 13 | (import.meta as any).hot.accept(); 14 | } -------------------------------------------------------------------------------- /apps/publish/client/src/utils/getPackages.ts: -------------------------------------------------------------------------------- 1 | import { IPackageInfo } from '../components/App'; 2 | 3 | export const getPackages = async (): Promise => { 4 | const data = await fetch('http://localhost:3000/getPackages'); 5 | const json_data = (await data.json()) as string[]; 6 | return json_data.map((package_name) => ({ name: package_name, checked: false })); 7 | }; 8 | -------------------------------------------------------------------------------- /apps/publish/client/src/utils/publishPackages.ts: -------------------------------------------------------------------------------- 1 | export const publishPackages = async (packages: string[]) => { 2 | return fetch('http://localhost:3000/publishPackages', { 3 | method: 'POST', 4 | headers: { 5 | Accept: 'application/json', 6 | 'Content-Type': 'application/json' 7 | }, 8 | body: JSON.stringify(packages) 9 | }); 10 | }; 11 | -------------------------------------------------------------------------------- /apps/publish/client/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": [ 3 | "src", 4 | "types" 5 | ], 6 | "compilerOptions": { 7 | "module": "esnext", 8 | "target": "esnext", 9 | "moduleResolution": "node", 10 | "jsx": "preserve", 11 | "baseUrl": "./", 12 | "paths": {}, 13 | "noEmit": true, 14 | "strict": true, 15 | "skipLibCheck": true, 16 | "forceConsistentCasingInFileNames": true, 17 | "resolveJsonModule": true, 18 | "allowSyntheticDefaultImports": true 19 | } 20 | } -------------------------------------------------------------------------------- /apps/publish/server/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "server", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "npx concurrently -n tsc,server \"tsc -w\" \"nodemon ./dist/index.js\"" 8 | }, 9 | "keywords": [], 10 | "author": "Safwan Shaheer ", 11 | "license": "MIT", 12 | "dependencies": { 13 | "cors": "^2.8.5", 14 | "express": "^4.17.1", 15 | "ws": "^7.4.4" 16 | }, 17 | "devDependencies": { 18 | "concurrently": "^6.0.0" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /apps/publish/server/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "lib": [ 4 | "ESNext" 5 | ], 6 | "baseUrl": "./", 7 | "module": "commonjs", 8 | "moduleResolution": "node", 9 | "target": "ESNext", 10 | "strict": true, 11 | "esModuleInterop": true, 12 | "skipLibCheck": true, 13 | "forceConsistentCasingInFileNames": true, 14 | "watch": false, 15 | "declaration": true, 16 | "sourceMap": true, 17 | "noUnusedLocals": false, 18 | "incremental": false, 19 | "outDir": "./dist", 20 | "rootDir": "./", 21 | }, 22 | "include": [ 23 | "./index.ts" 24 | ] 25 | } -------------------------------------------------------------------------------- /docs/.gitignore: -------------------------------------------------------------------------------- 1 | # tailwindcss cli output file 2 | /static/css/tailwind.css -------------------------------------------------------------------------------- /docs/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [require.resolve('@docusaurus/core/lib/babel/preset')], 3 | }; 4 | -------------------------------------------------------------------------------- /docs/docs/notion-formula/Usage/Integration.mdx: -------------------------------------------------------------------------------- 1 | Since this package only generates notion formula there is no restrictions to which package you could use. 2 | 3 | This package integrates nicely with the [core](https://www.npmjs.com/package/@nishans/core) package, when you are trying create a schema. 4 | -------------------------------------------------------------------------------- /docs/docs/root/Introduction/Architecture.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Devorein/Nishan/5c258d07d6a5a9ea45a3b44ec04eb19018f4deda/docs/docs/root/Introduction/Architecture.md -------------------------------------------------------------------------------- /docs/docs/root/Introduction/Features.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: Features 3 | title: Features 4 | sidebar_label: Features 5 | slug: /features 6 | --- 7 | 8 | 1. **Ease of Use**: Nishan was designed to be easy to use and intuitive. 9 | 2. **Automate everything**: Almost everything that is possible in Notion can be done through nishan. 10 | 3. **Minimum overhead**: All you need is your notion token and you are ready to go. 11 | 4. **API Usage interval**: Nishan makes sure that there is a specific time duration between each api request. 12 | 5. **Typescript Support**: Nishan was built with typescript support in mind. 13 | 6. **Minimum api calls**: Nishan guarantees that each api request is optimal and performant. 14 | -------------------------------------------------------------------------------- /docs/docs/root/Introduction/Understanding Nishan.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | id: Understanding Nishan 3 | title: Understanding Nishan 4 | sidebar_label: Understanding Nishan 5 | slug: /understanding_nishan 6 | --- 7 | 8 | Nishan was designed to emulate the actual notion client whether it be web,mobile or desktop as close as possible. 9 | It has a cache layer (under development) adding the following benefits:- 10 | 11 | 1. Reduce the api call amounts 12 | 2. Faster retrieval of data 13 | 14 | Nishan has class for almost every type of data there is in notion. eg Block, Page, Space etc, with almost all the required methods. 15 | 16 | 17 | -------------------------------------------------------------------------------- /docs/docs/utils/Introduction/Features.md: -------------------------------------------------------------------------------- 1 | ## Easy to use api 2 | 3 | Every functions exported by the package are straight forward and easy to use. 4 | 5 | ## Multi purpose 6 | 7 | Integrates nicely with a lot of packages from Nishan's ecosystem, especially with `core` and `notion-formula`. 8 | 9 | ## Typescript Support 10 | 11 | Typescript support right out of the box for static typechecking. Every function is properly commented and documented. -------------------------------------------------------------------------------- /docs/docs/utils/Modules/uuidConversion.md: -------------------------------------------------------------------------------- 1 | This module exports two simple functions to transform between regular id and notion compatible id. 2 | 3 | ## idToUuid 4 | 5 | As the name suggests this function converts id to uuid 6 | 7 | ```js 8 | const {idToUuid} = require("@nishans/utils"); 9 | 10 | console.log(idToUuid("dd721d8bbf354036bdcde9378e8b7e83")); 11 | // dd721d8b-bf35-4036-bdcd-e9378e8b7e83 12 | ``` 13 | 14 | ## uuidToId 15 | 16 | Converts a regular id to a notion compatible uuid 17 | 18 | ```js 19 | const {idToUuid} = require("@nishans/utils"); 20 | 21 | console.log(idToUuid("dd721d8b-bf35-4036-bdcd-e9378e8b7e83")); 22 | // dd721d8bbf354036bdcde9378e8b7e83 23 | ``` -------------------------------------------------------------------------------- /docs/src/css/tailwind.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; -------------------------------------------------------------------------------- /docs/src/pages/styles.module.css: -------------------------------------------------------------------------------- 1 | .heroBanner { 2 | padding: 4rem 0; 3 | text-align: center; 4 | position: relative; 5 | overflow: hidden; 6 | } 7 | 8 | @media screen and (max-width: 966px) { 9 | .heroBanner { 10 | padding: 2rem; 11 | } 12 | } 13 | 14 | .buttons { 15 | display: flex; 16 | align-items: center; 17 | justify-content: center; 18 | } 19 | 20 | .features { 21 | display: flex; 22 | align-items: center; 23 | padding: 2rem 0; 24 | width: 100%; 25 | } 26 | 27 | .featureImage { 28 | height: 200px; 29 | width: 200px; 30 | } 31 | -------------------------------------------------------------------------------- /docs/src/theme/NavbarItem/styles.module.css: -------------------------------------------------------------------------------- 1 | .dropdownItem { 2 | display: flex; 3 | align-items: center; 4 | } 5 | 6 | .dropdownItemLabel{ 7 | margin-left: 10px; 8 | } -------------------------------------------------------------------------------- /docs/src/theme/TOC/styles.module.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | .tableOfContents { 9 | display: inherit; 10 | max-height: calc(100vh - (var(--ifm-navbar-height) + 2rem)); 11 | overflow-y: auto; 12 | position: sticky; 13 | top: calc(var(--ifm-navbar-height) + 2rem); 14 | } 15 | 16 | @media only screen and (max-width: 996px) { 17 | .tableOfContents { 18 | display: none; 19 | } 20 | 21 | .docItemContainer { 22 | padding: 0 0.3rem; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /docs/static/.nojekyll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Devorein/Nishan/5c258d07d6a5a9ea45a3b44ec04eb19018f4deda/docs/static/.nojekyll -------------------------------------------------------------------------------- /docs/static/img/endpoints/logo_standalone.svg: -------------------------------------------------------------------------------- 1 | logo_standalone_8 -------------------------------------------------------------------------------- /docs/static/img/logos/discord_dark_24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Devorein/Nishan/5c258d07d6a5a9ea45a3b44ec04eb19018f4deda/docs/static/img/logos/discord_dark_24.png -------------------------------------------------------------------------------- /docs/static/img/logos/discord_light_24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Devorein/Nishan/5c258d07d6a5a9ea45a3b44ec04eb19018f4deda/docs/static/img/logos/discord_light_24.png -------------------------------------------------------------------------------- /docs/static/img/logos/github_dark_24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Devorein/Nishan/5c258d07d6a5a9ea45a3b44ec04eb19018f4deda/docs/static/img/logos/github_dark_24.png -------------------------------------------------------------------------------- /docs/static/img/logos/github_light_24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Devorein/Nishan/5c258d07d6a5a9ea45a3b44ec04eb19018f4deda/docs/static/img/logos/github_light_24.png -------------------------------------------------------------------------------- /docs/static/img/logos/npm_dark_24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Devorein/Nishan/5c258d07d6a5a9ea45a3b44ec04eb19018f4deda/docs/static/img/logos/npm_dark_24.png -------------------------------------------------------------------------------- /docs/static/img/logos/npm_light_24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Devorein/Nishan/5c258d07d6a5a9ea45a3b44ec04eb19018f4deda/docs/static/img/logos/npm_light_24.png -------------------------------------------------------------------------------- /docs/static/img/root/Logo@175px.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Devorein/Nishan/5c258d07d6a5a9ea45a3b44ec04eb19018f4deda/docs/static/img/root/Logo@175px.png -------------------------------------------------------------------------------- /docs/static/img/root/Logo@350px.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Devorein/Nishan/5c258d07d6a5a9ea45a3b44ec04eb19018f4deda/docs/static/img/root/Logo@350px.png -------------------------------------------------------------------------------- /docs/static/img/root/logo@88px.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Devorein/Nishan/5c258d07d6a5a9ea45a3b44ec04eb19018f4deda/docs/static/img/root/logo@88px.png -------------------------------------------------------------------------------- /docs/static/img/types/logo_standalone.svg: -------------------------------------------------------------------------------- 1 | logo_standalone_7.d.ts -------------------------------------------------------------------------------- /docs/static/img/utils/inlineblocks/text_bold_extra_italic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Devorein/Nishan/5c258d07d6a5a9ea45a3b44ec04eb19018f4deda/docs/static/img/utils/inlineblocks/text_bold_extra_italic.png -------------------------------------------------------------------------------- /docs/static/img/utils/inlineblocks/text_extra.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Devorein/Nishan/5c258d07d6a5a9ea45a3b44ec04eb19018f4deda/docs/static/img/utils/inlineblocks/text_extra.png -------------------------------------------------------------------------------- /docs/static/img/utils/inlineblocks/text_red_bg_extra_blue_bold.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Devorein/Nishan/5c258d07d6a5a9ea45a3b44ec04eb19018f4deda/docs/static/img/utils/inlineblocks/text_red_bg_extra_blue_bold.png -------------------------------------------------------------------------------- /docs/tailwind.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | purge: [], 3 | darkMode: false, // or 'media' or 'class' 4 | theme: { 5 | extend: {}, 6 | }, 7 | variants: { 8 | extend: {}, 9 | }, 10 | plugins: [], 11 | } 12 | -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = async () => { 2 | return { 3 | rootDir: process.cwd(), 4 | testTimeout: 30000, 5 | testEnvironment: 'node', 6 | verbose: true, 7 | testPathIgnorePatterns: [ '/node_modules', '/dist' ], 8 | modulePathIgnorePatterns: [ '/dist' ], 9 | roots: [ '/tests' ], 10 | testMatch: [ '/tests/**/*.test.ts' ], 11 | transform: { 12 | '^.+\\.(ts)$': 'ts-jest' 13 | }, 14 | collectCoverage: true, 15 | coverageDirectory: "./coverage", 16 | coverageThreshold: { 17 | "global": { 18 | "branches": 95, 19 | "functions": 95, 20 | "lines": 95, 21 | "statements": -10 22 | } 23 | } 24 | }; 25 | }; -------------------------------------------------------------------------------- /lerna.json: -------------------------------------------------------------------------------- 1 | { 2 | "packages": [ 3 | "packages/*" 4 | ], 5 | "version": "0.0.0", 6 | "npmClient": "yarn", 7 | "useWorkspaces": true 8 | } -------------------------------------------------------------------------------- /packages/cache/libs/constructSyncRecordsParams.ts: -------------------------------------------------------------------------------- 1 | import { SyncRecordValuesTuple } from '@nishans/endpoints'; 2 | import { INotionEndpoints } from '@nishans/types'; 3 | 4 | export function constructSyncRecordsParams(args: SyncRecordValuesTuple) { 5 | const sync_record_values: INotionEndpoints['syncRecordValues']['payload']['requests'][0][] = []; 6 | // Iterate through the passed array argument and construct sync_record argument 7 | args.forEach((arg) => { 8 | sync_record_values.push({ id: arg[0], table: arg[1], version: 0 }); 9 | }); 10 | return sync_record_values; 11 | } 12 | -------------------------------------------------------------------------------- /packages/cache/libs/createDefaultCache.ts: -------------------------------------------------------------------------------- 1 | import { NotionConstants } from '@nishans/constants'; 2 | import { INotionCache } from '@nishans/types'; 3 | 4 | export function createDefaultCache () { 5 | const cache: INotionCache = {} as any; 6 | NotionConstants.dataTypes().forEach((data_type) => (cache[data_type] = new Map())); 7 | return cache; 8 | } 9 | -------------------------------------------------------------------------------- /packages/cache/libs/createDefaultCacheInitializeTracker.ts: -------------------------------------------------------------------------------- 1 | import { NotionConstants } from '@nishans/constants'; 2 | import { NotionCacheInitializerTracker } from '@nishans/types'; 3 | 4 | export function createDefaultCacheInitializeTracker () { 5 | const cache_init_tracker: NotionCacheInitializerTracker = {} as any; 6 | NotionConstants.dataTypes().forEach((data_type) => (cache_init_tracker[data_type] = new Map())); 7 | return cache_init_tracker; 8 | } 9 | -------------------------------------------------------------------------------- /packages/cache/libs/extractSpaceAndParentId.ts: -------------------------------------------------------------------------------- 1 | import { SyncRecordValuesTuple } from '@nishans/endpoints'; 2 | import { TBlock } from '@nishans/types'; 3 | 4 | export function extractSpaceAndParentId(data: TBlock) { 5 | const sync_record_values: SyncRecordValuesTuple = []; 6 | if (data.parent_table === 'space') 7 | sync_record_values.push([data.parent_id, 'space']); 8 | else { 9 | sync_record_values.push([data.parent_id, 'block']); 10 | sync_record_values.push([data.space_id, 'space']); 11 | } 12 | return sync_record_values; 13 | } 14 | -------------------------------------------------------------------------------- /packages/cache/libs/fetchDataOrReturnCached.ts: -------------------------------------------------------------------------------- 1 | import { TData, TDataType } from '@nishans/types'; 2 | import { INotionCacheOptions, NotionCache } from './'; 3 | 4 | /** 5 | * Fetch data from notion's db if it doesn't exist in the cache 6 | * @param table The table of the data 7 | * @param id the id of the data 8 | * @param options Notion cache options 9 | */ 10 | export async function fetchDataOrReturnCached ( 11 | table: TDataType, 12 | id: string, 13 | options: Omit 14 | ): Promise { 15 | return (await NotionCache.fetchMultipleDataOrReturnCached([ [ id, table ] ], options))[table][0] as any; 16 | } 17 | -------------------------------------------------------------------------------- /packages/cache/libs/returnNonCachedData.ts: -------------------------------------------------------------------------------- 1 | import { SyncRecordValuesTuple } from '@nishans/endpoints'; 2 | import { INotionCache } from '@nishans/types'; 3 | 4 | /** 5 | * Returns the id and data_type tuple passed that is not present in the cache 6 | * @param update_cache_param Array of tuple of id and data_type to look for in the cache 7 | * @returns 8 | */ 9 | export function returnNonCachedData( 10 | update_cache_param: SyncRecordValuesTuple, 11 | cache: INotionCache 12 | ): SyncRecordValuesTuple { 13 | return update_cache_param.filter( 14 | (info) => !Boolean(cache[info[1]].get(info[0])) 15 | ); 16 | } 17 | -------------------------------------------------------------------------------- /packages/cache/libs/types.ts: -------------------------------------------------------------------------------- 1 | import { INotionEndpointsOptions } from '@nishans/endpoints'; 2 | import { INotionCache, NotionCacheInitializerTracker } from '@nishans/types'; 3 | export interface INotionCacheOptions extends INotionEndpointsOptions { 4 | cache: INotionCache; 5 | cache_init_tracker: NotionCacheInitializerTracker; 6 | } 7 | -------------------------------------------------------------------------------- /packages/cache/libs/updateCacheIfNotPresent.ts: -------------------------------------------------------------------------------- 1 | import { SyncRecordValuesTuple } from '@nishans/endpoints'; 2 | import { INotionCacheOptions, NotionCache } from './'; 3 | 4 | /** 5 | * Fetches notion data only if it doesn't exist in the cache 6 | * @param arg Array of id and data_type tuple to fetch from notion and store 7 | */ 8 | export async function updateCacheIfNotPresent( 9 | args: SyncRecordValuesTuple, 10 | options: Omit 11 | ) { 12 | await NotionCache.constructAndSyncRecordsParams( 13 | args.filter((arg) => !options.cache[arg[1]].get(arg[0])), 14 | options 15 | ); 16 | } 17 | -------------------------------------------------------------------------------- /packages/cache/libs/updateCacheManually.ts: -------------------------------------------------------------------------------- 1 | import { SyncRecordValuesTuple } from '@nishans/endpoints'; 2 | import { INotionCacheOptions, NotionCache } from './'; 3 | 4 | /** 5 | * Fetches data from notions server and store within the cache 6 | * @param args The array of id and data_type tuple to fetch and store 7 | */ 8 | export async function updateCacheManually( 9 | args: SyncRecordValuesTuple, 10 | options: Omit 11 | ) { 12 | await NotionCache.constructAndSyncRecordsParams(args, options); 13 | } 14 | -------------------------------------------------------------------------------- /packages/cache/tests/constructSyncRecordsParams.test.ts: -------------------------------------------------------------------------------- 1 | import { NotionCache } from '../libs'; 2 | 3 | afterEach(() => { 4 | jest.restoreAllMocks(); 5 | }); 6 | 7 | describe('constructSyncRecordsParams', () => { 8 | it(`should work correctly`, async () => { 9 | const result = NotionCache.constructSyncRecordsParams([ [ '123', 'block' ] ]); 10 | expect(result).toStrictEqual([ 11 | { 12 | table: 'block', 13 | id: '123', 14 | version: 0 15 | } 16 | ]); 17 | }); 18 | }); 19 | -------------------------------------------------------------------------------- /packages/cache/tests/createDefaultCache.test.ts: -------------------------------------------------------------------------------- 1 | import { NotionCache } from '../libs'; 2 | 3 | afterEach(() => { 4 | jest.restoreAllMocks(); 5 | }); 6 | 7 | it(`NotionCache.createDefaultCache`, () => { 8 | expect(NotionCache.validateCache(NotionCache.createDefaultCache())).toBeTruthy(); 9 | }); 10 | -------------------------------------------------------------------------------- /packages/cache/tests/extractNotionUserIds.test.ts: -------------------------------------------------------------------------------- 1 | import { NotionCache } from '../libs'; 2 | 3 | afterEach(() => { 4 | jest.restoreAllMocks(); 5 | }); 6 | 7 | it(`Should work correctly`, () => { 8 | const extracted_notion_user_ids = NotionCache.extractNotionUserIds({ 9 | last_edited_by_id: 'notion_user_1', 10 | created_by_id: 'notion_user_2', 11 | permissions: [ 12 | { 13 | type: 'user_permission', 14 | user_id: 'notion_user_3' 15 | }, 16 | { 17 | type: 'space_permission' 18 | }, 19 | { 20 | type: 'user_permission', 21 | user_id: 'notion_user_1' 22 | } 23 | ] 24 | } as any); 25 | expect(extracted_notion_user_ids).toStrictEqual([ 'notion_user_3', 'notion_user_1', 'notion_user_2' ]); 26 | }); 27 | -------------------------------------------------------------------------------- /packages/cache/tests/extractSpaceAndParentId.test.ts: -------------------------------------------------------------------------------- 1 | import { NotionCache } from '../libs'; 2 | 3 | afterEach(() => { 4 | jest.restoreAllMocks(); 5 | }); 6 | 7 | it(`parent_table=space`, () => { 8 | expect(NotionCache.extractSpaceAndParentId({ parent_table: 'space', parent_id: 'space_1' } as any)).toStrictEqual([ 9 | [ 'space_1', 'space' ] 10 | ]); 11 | }); 12 | 13 | it(`parent_table=block`, () => { 14 | expect( 15 | NotionCache.extractSpaceAndParentId({ 16 | parent_table: 'block', 17 | parent_id: 'block_1', 18 | space_id: 'space_1' 19 | } as any) 20 | ).toStrictEqual([ [ 'block_1', 'block' ], [ 'space_1', 'space' ] ]); 21 | }); 22 | -------------------------------------------------------------------------------- /packages/cache/tests/fetchDataOrReturnCached.test.ts: -------------------------------------------------------------------------------- 1 | import { INotionCache } from '@nishans/types'; 2 | import { NotionCache } from '../libs'; 3 | 4 | afterEach(() => { 5 | jest.restoreAllMocks(); 6 | }); 7 | 8 | it(`data exists in cache`, async () => { 9 | const block_1 = { 10 | id: 'block_1' 11 | }, 12 | cache: INotionCache = { 13 | block: new Map([ [ 'block_1', block_1 ] ]) 14 | } as any; 15 | const data = await NotionCache.fetchDataOrReturnCached('block', 'block_1', { 16 | cache, 17 | token: 'token', 18 | user_id: 'user_root_1' 19 | }); 20 | expect(data).toBe(block_1); 21 | }); 22 | -------------------------------------------------------------------------------- /packages/cache/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.shared.json", 3 | "include": [ 4 | "./libs/index.ts", 5 | "./experiment" 6 | ], 7 | "compilerOptions": { 8 | "outDir": "./dist", 9 | "rootDir": "./" 10 | } 11 | } -------------------------------------------------------------------------------- /packages/cli/libs/types.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Devorein/Nishan/5c258d07d6a5a9ea45a3b44ec04eb19018f4deda/packages/cli/libs/types.ts -------------------------------------------------------------------------------- /packages/cli/libs/utils/index.ts: -------------------------------------------------------------------------------- 1 | export * from './setIdentifierPositionalArgs'; 2 | -------------------------------------------------------------------------------- /packages/cli/libs/utils/setIdentifierPositionalArgs.ts: -------------------------------------------------------------------------------- 1 | import yargs from 'yargs'; 2 | 3 | export function setIdentifierPositionalArgs (yargs: yargs.Argv>) { 4 | yargs.positional('id', { 5 | describe: 'Id of the page to get', 6 | type: 'string', 7 | alias: 'i' 8 | }).required; 9 | 10 | yargs.positional('title', { 11 | describe: 'title of the page to get', 12 | type: 'string', 13 | alias: 't' 14 | }).required; 15 | } 16 | -------------------------------------------------------------------------------- /packages/cli/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.shared.json", 3 | "include": [ 4 | "./libs/index.ts", 5 | "./experiment", 6 | "./examples" 7 | ], 8 | "compilerOptions": { 9 | "outDir": "./dist", 10 | "rootDir": "./", 11 | }, 12 | } -------------------------------------------------------------------------------- /packages/cms/libs/index.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Devorein/Nishan/5c258d07d6a5a9ea45a3b44ec04eb19018f4deda/packages/cms/libs/index.ts -------------------------------------------------------------------------------- /packages/cms/tests/index.test.ts: -------------------------------------------------------------------------------- 1 | it('Should Work', () => { 2 | expect(true).toBe(true); 3 | }); -------------------------------------------------------------------------------- /packages/cms/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.shared.json", 3 | "include": [ 4 | "./libs/index.ts", 5 | "./experiment", 6 | "./examples" 7 | ], 8 | "compilerOptions": { 9 | "outDir": "./dist", 10 | "rootDir": "./", 11 | }, 12 | } -------------------------------------------------------------------------------- /packages/constants/libs/bgColorTypes.ts: -------------------------------------------------------------------------------- 1 | import { TBGColor } from '@nishans/types'; 2 | 3 | export const createBgColorTypes = () => { 4 | return [ 5 | 'default_background', 6 | 'gray_background', 7 | 'brown_background', 8 | 'orange_background', 9 | 'yellow_background', 10 | 'teal_background', 11 | 'blue_background', 12 | 'purple_background', 13 | 'pink_background', 14 | 'red_background' 15 | ] as TBGColor[]; 16 | }; 17 | -------------------------------------------------------------------------------- /packages/constants/libs/colorTypes.ts: -------------------------------------------------------------------------------- 1 | import { TTextColor } from '@nishans/types'; 2 | 3 | export const createColorTypes = () => { 4 | return [ 'default', 'gray', 'brown', 'orange', 'yellow', 'teal', 'blue', 'purple', 'pink', 'red' ] as TTextColor[]; 5 | }; 6 | -------------------------------------------------------------------------------- /packages/constants/libs/dataTypes.ts: -------------------------------------------------------------------------------- 1 | import { TDataType } from '@nishans/types'; 2 | 3 | export const createDataTypes = () => { 4 | return [ 5 | 'block', 6 | 'collection', 7 | 'collection_view', 8 | 'space', 9 | 'notion_user', 10 | 'space_view', 11 | 'user_root', 12 | 'user_settings', 13 | 'discussion', 14 | 'comment', 15 | 'follow', 16 | 'slack_integration', 17 | 'page_visits', 18 | 'activity', 19 | 'notification' 20 | ] as TDataType[]; 21 | }; 22 | -------------------------------------------------------------------------------- /packages/constants/libs/operationCommands.ts: -------------------------------------------------------------------------------- 1 | import { TOperationCommand } from '@nishans/types'; 2 | 3 | export const createOperationCommands = () => 4 | [ 5 | 'setPermissionItem', 6 | 'listRemove', 7 | 'listBefore', 8 | 'listAfter', 9 | 'update', 10 | 'set', 11 | 'keyedObjectListUpdate', 12 | 'keyedObjectListAfter' 13 | ] as TOperationCommand[]; 14 | -------------------------------------------------------------------------------- /packages/constants/libs/schemaUnitTypes.ts: -------------------------------------------------------------------------------- 1 | import { TSchemaUnitType } from '@nishans/types'; 2 | 3 | export const createSchemaUnitTypes = () => { 4 | return [ 5 | 'text', 6 | 'number', 7 | 'select', 8 | 'multi_select', 9 | 'title', 10 | 'date', 11 | 'person', 12 | 'file', 13 | 'checkbox', 14 | 'url', 15 | 'email', 16 | 'phone_number', 17 | 'formula', 18 | 'relation', 19 | 'rollup', 20 | 'created_time', 21 | 'created_by', 22 | 'last_edited_time', 23 | 'last_edited_by' 24 | ] as TSchemaUnitType[]; 25 | }; 26 | -------------------------------------------------------------------------------- /packages/constants/libs/viewTypes.ts: -------------------------------------------------------------------------------- 1 | import { TViewType } from '@nishans/types'; 2 | 3 | export const createViewTypes = () => { 4 | return [ 'board', 'gallery', 'list', 'timeline', 'table', 'calendar' ] as TViewType[]; 5 | }; 6 | -------------------------------------------------------------------------------- /packages/constants/tests/viewTypes.test.ts: -------------------------------------------------------------------------------- 1 | import { TViewType } from '@nishans/types'; 2 | import { NotionConstants } from '../libs'; 3 | 4 | it('NotionConstants.view_types', () => { 5 | const view_types = NotionConstants.viewTypes(); 6 | const view_types_map: Map = new Map(); 7 | view_types.forEach((view_type) => view_types_map.set(view_type, true)); 8 | 9 | const expected_view_types: TViewType[] = [ 'board', 'gallery', 'list', 'timeline', 'table', 'calendar' ]; 10 | 11 | expect(view_types.length === expected_view_types.length).toBe(true); 12 | expected_view_types.forEach((expected_view_type) => expect(view_types_map.get(expected_view_type)).toBe(true)); 13 | }); 14 | -------------------------------------------------------------------------------- /packages/constants/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.shared.json", 3 | "include": [ 4 | "./libs/index.ts", 5 | "./experiment", 6 | "./examples" 7 | ], 8 | "compilerOptions": { 9 | "outDir": "./dist", 10 | "rootDir": "./", 11 | }, 12 | } -------------------------------------------------------------------------------- /packages/core/examples/README.md: -------------------------------------------------------------------------------- 1 | # Nishan-workflows 2 | 3 | A bunch of personal workflows using nishan, showing off its capabilities and usage 4 | 5 | ## Requirements 6 | 7 | 1. Make sure all the dependencies are install 8 | 2. Run `npm run build` to compile ts to js 9 | 3. In the `env.ts` file paste your own notion token 10 | 4. Navigate to the dist folder and execute the index file 11 | -------------------------------------------------------------------------------- /packages/core/examples/Workflow 1/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Devorein/Nishan/5c258d07d6a5a9ea45a3b44ec04eb19018f4deda/packages/core/examples/Workflow 1/README.md -------------------------------------------------------------------------------- /packages/core/examples/Workflow 1/data/difficulty.ts: -------------------------------------------------------------------------------- 1 | import { SelectOption } from '@nishans/types'; 2 | 3 | export default [ 4 | { 5 | color: 'red', 6 | value: 'Hard' 7 | }, 8 | { 9 | color: 'yellow', 10 | value: 'Medium' 11 | }, 12 | { 13 | color: 'green', 14 | value: 'Easy' 15 | } 16 | ] as (Omit)[]; 17 | -------------------------------------------------------------------------------- /packages/core/examples/Workflow 1/data/index.ts: -------------------------------------------------------------------------------- 1 | import phase from './phase'; 2 | import priority from './priority'; 3 | import status from './status'; 4 | import difficulty from './difficulty'; 5 | import subject from './subject'; 6 | import purpose from './purpose'; 7 | import source from './source'; 8 | export * from './category'; 9 | export * from './ecosystem'; 10 | 11 | export { source, phase, priority, status, subject, difficulty, purpose }; 12 | -------------------------------------------------------------------------------- /packages/core/examples/Workflow 1/data/phase.ts: -------------------------------------------------------------------------------- 1 | import { SelectOption } from '@nishans/types'; 2 | 3 | export default [ 4 | { 5 | color: 'red', 6 | value: 'Learn' 7 | }, 8 | { 9 | color: 'yellow', 10 | value: 'Revise' 11 | }, 12 | { 13 | color: 'green', 14 | value: 'Practice' 15 | } 16 | ] as (Omit)[]; 17 | -------------------------------------------------------------------------------- /packages/core/examples/Workflow 1/data/priority.ts: -------------------------------------------------------------------------------- 1 | import { SelectOption } from '@nishans/types'; 2 | 3 | export default [ 4 | { 5 | color: 'red', 6 | value: 'High' 7 | }, 8 | { 9 | color: 'yellow', 10 | value: 'Medium' 11 | }, 12 | { 13 | color: 'green', 14 | value: 'Low' 15 | } 16 | ] as (Omit)[]; 17 | -------------------------------------------------------------------------------- /packages/core/examples/Workflow 1/data/purpose.ts: -------------------------------------------------------------------------------- 1 | import { SelectOption } from '@nishans/types'; 2 | 3 | export default [ 4 | { 5 | color: 'default', 6 | value: 'Learning' 7 | }, 8 | { 9 | color: 'default', 10 | value: 'Practice' 11 | }, 12 | { 13 | color: 'default', 14 | value: 'Project' 15 | }, 16 | { 17 | color: 'default', 18 | value: 'Revise' 19 | }, 20 | { 21 | color: 'default', 22 | value: 'Organization' 23 | }, 24 | { 25 | color: 'default', 26 | value: 'Resources' 27 | }, 28 | { 29 | color: 'default', 30 | value: 'Online' 31 | } 32 | ] as (Omit)[]; 33 | -------------------------------------------------------------------------------- /packages/core/examples/Workflow 1/data/source.ts: -------------------------------------------------------------------------------- 1 | import { SelectOption } from '@nishans/types'; 2 | 3 | export default [ 4 | { 5 | color: 'default', 6 | value: 'EBook' 7 | }, 8 | { 9 | color: 'default', 10 | value: 'Course' 11 | }, 12 | { 13 | color: 'default', 14 | value: 'Github' 15 | }, 16 | { 17 | color: 'default', 18 | value: 'Docs' 19 | }, 20 | { 21 | color: 'default', 22 | value: 'Local' 23 | }, 24 | { 25 | color: 'default', 26 | value: 'Web' 27 | } 28 | ] as (Omit)[]; 29 | -------------------------------------------------------------------------------- /packages/core/examples/Workflow 1/data/status.ts: -------------------------------------------------------------------------------- 1 | import { SelectOption } from '@nishans/types'; 2 | 3 | export default [ 4 | { 5 | color: 'red', 6 | value: 'To Complete' 7 | }, 8 | { 9 | color: 'yellow', 10 | value: 'Completing' 11 | }, 12 | { 13 | color: 'green', 14 | value: 'Completed' 15 | } 16 | ] as (Omit)[]; 17 | -------------------------------------------------------------------------------- /packages/core/examples/Workflow 1/data/utils.ts: -------------------------------------------------------------------------------- 1 | export type ElementType> = T extends ReadonlyArray ? ElementType : never -------------------------------------------------------------------------------- /packages/core/examples/Workflow 1/index.ts: -------------------------------------------------------------------------------- 1 | import '../env'; 2 | import step1 from './step_1'; 3 | import step2 from './step_2'; 4 | import step3 from './step_3'; 5 | import step4 from './step_4'; 6 | 7 | (async function () { 8 | // Pass your own user family name and space name to get the correct user and space instance 9 | const target_page = await step1('Shaheer', "Safwan's Notion"); 10 | await step2(target_page); 11 | await step3(target_page); 12 | await step4(target_page); 13 | })(); 14 | -------------------------------------------------------------------------------- /packages/core/examples/Workflow 1/step_1/readme.md: -------------------------------------------------------------------------------- 1 | # Workflow 1 2 | 3 | This workflow creates three root pages with appropriate contents for the follow purposes 4 | 5 | 1. Article: A cvp containing list of articles that has to be completed 6 | 2. Todo: A cvp for a simple todo list 7 | 3. Daily: A cvp to check my daily usage of various developers concerned social media and sites 8 | -------------------------------------------------------------------------------- /packages/core/examples/Workflow 1/step_2/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Devorein/Nishan/5c258d07d6a5a9ea45a3b44ec04eb19018f4deda/packages/core/examples/Workflow 1/step_2/README.md -------------------------------------------------------------------------------- /packages/core/examples/Workflow 1/step_3/readme.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Devorein/Nishan/5c258d07d6a5a9ea45a3b44ec04eb19018f4deda/packages/core/examples/Workflow 1/step_3/readme.md -------------------------------------------------------------------------------- /packages/core/examples/Workflow 1/step_4/readme.md: -------------------------------------------------------------------------------- 1 | # Workflow 4 2 | 3 | This is a personal workflow thus might not be applicable for your specific use case -------------------------------------------------------------------------------- /packages/core/libs/Api/Block/index.ts: -------------------------------------------------------------------------------- 1 | import Block from './Block'; 2 | import CollectionBlock from './CollectionBlock'; 3 | import CollectionView from './CollectionView'; 4 | import CollectionViewPage from './CollectionViewPage'; 5 | import Page from './Page'; 6 | import PageBlock from './PageBlock'; 7 | 8 | export { PageBlock, Block, CollectionViewPage, CollectionView, Page, CollectionBlock }; 9 | -------------------------------------------------------------------------------- /packages/core/libs/Api/Comment.ts: -------------------------------------------------------------------------------- 1 | import { ICommentUpdateInput } from '@nishans/discourse'; 2 | import { IComment } from '@nishans/types'; 3 | import { INotionCoreOptions } from '../'; 4 | import NotionData from './Data'; 5 | 6 | export default class Comment extends NotionData { 7 | constructor (arg: INotionCoreOptions) { 8 | super({ ...arg, type: 'comment' }); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /packages/core/libs/Api/UserSettings.ts: -------------------------------------------------------------------------------- 1 | import { IUserSettings } from '@nishans/types'; 2 | import { INotionCoreOptions, IUserSettingsUpdateInput } from '../'; 3 | import Data from './Data'; 4 | 5 | /** 6 | * A class to represent user settings of Notion 7 | * @noInheritDoc 8 | */ 9 | class UserSettings extends Data { 10 | constructor (arg: INotionCoreOptions) { 11 | super({ ...arg, type: 'user_settings' }); 12 | } 13 | } 14 | 15 | export default UserSettings; 16 | -------------------------------------------------------------------------------- /packages/core/libs/Api/View/BoardView.ts: -------------------------------------------------------------------------------- 1 | import { IBoardView } from '@nishans/types'; 2 | import { INotionCoreOptions } from '../../'; 3 | import Aggregator from './Aggregator'; 4 | 5 | /** 6 | * A class to represent board view of Notion 7 | * @noInheritDoc 8 | */ 9 | 10 | class BoardView extends Aggregator>> { 11 | constructor (arg: INotionCoreOptions) { 12 | super({ ...arg }); 13 | } 14 | } 15 | 16 | export default BoardView; 17 | -------------------------------------------------------------------------------- /packages/core/libs/Api/View/CalendarView.ts: -------------------------------------------------------------------------------- 1 | import { ICalendarView } from '@nishans/types'; 2 | import { INotionCoreOptions } from '../../'; 3 | import View from './View'; 4 | 5 | /** 6 | * A class to represent calendar view of Notion 7 | * @noInheritDoc 8 | */ 9 | 10 | class CalendarView extends View>> { 11 | constructor (arg: INotionCoreOptions) { 12 | super({ ...arg }); 13 | } 14 | } 15 | 16 | export default CalendarView; 17 | -------------------------------------------------------------------------------- /packages/core/libs/Api/View/GalleryView.ts: -------------------------------------------------------------------------------- 1 | import { IGalleryView } from '@nishans/types'; 2 | import { INotionCoreOptions } from '../../'; 3 | import View from './View'; 4 | 5 | /** 6 | * A class to represent gallery view of Notion 7 | * @noInheritDoc 8 | */ 9 | 10 | class GalleryView extends View>> { 11 | constructor (arg: INotionCoreOptions) { 12 | super({ ...arg }); 13 | } 14 | } 15 | 16 | export default GalleryView; 17 | -------------------------------------------------------------------------------- /packages/core/libs/Api/View/ListView.ts: -------------------------------------------------------------------------------- 1 | import { IListView } from '@nishans/types'; 2 | import { INotionCoreOptions } from '../../'; 3 | import View from './View'; 4 | 5 | /** 6 | * A class to represent list view of Notion 7 | * @noInheritDoc 8 | */ 9 | class ListView extends View>> { 10 | constructor (arg: INotionCoreOptions) { 11 | super({ ...arg }); 12 | } 13 | } 14 | 15 | export default ListView; 16 | -------------------------------------------------------------------------------- /packages/core/libs/Api/View/TableView.ts: -------------------------------------------------------------------------------- 1 | import { ITableView } from '@nishans/types'; 2 | import { INotionCoreOptions } from '../../'; 3 | import Aggregator from './Aggregator'; 4 | 5 | /** 6 | * A class to represent table view of Notion 7 | * @noInheritDoc 8 | */ 9 | class TableView extends Aggregator>> { 10 | constructor (arg: INotionCoreOptions) { 11 | super({ ...arg }); 12 | } 13 | } 14 | 15 | export default TableView; 16 | -------------------------------------------------------------------------------- /packages/core/libs/Api/View/TimelineView.ts: -------------------------------------------------------------------------------- 1 | import { ITimelineView } from '@nishans/types'; 2 | import { INotionCoreOptions } from '../../'; 3 | import Aggregator from './Aggregator'; 4 | 5 | /** 6 | * A class to represent timeline view of Notion 7 | * @noInheritDoc 8 | */ 9 | 10 | class TimelineView extends Aggregator< 11 | ITimelineView, 12 | Partial> 13 | > { 14 | constructor (arg: INotionCoreOptions) { 15 | super({ ...arg }); 16 | } 17 | } 18 | 19 | export default TimelineView; 20 | -------------------------------------------------------------------------------- /packages/core/libs/Api/View/index.ts: -------------------------------------------------------------------------------- 1 | import View from './View'; 2 | import CalendarView from './CalendarView'; 3 | import TableView from './TableView'; 4 | import ListView from './ListView'; 5 | import GalleryView from './GalleryView'; 6 | import TimelineView from './TimelineView'; 7 | import BoardView from './BoardView'; 8 | import ViewAggregator from './Aggregator'; 9 | 10 | export { ViewAggregator, View, CalendarView, TableView, ListView, GalleryView, TimelineView, BoardView }; 11 | -------------------------------------------------------------------------------- /packages/core/libs/CreateMaps/createBlockMap.ts: -------------------------------------------------------------------------------- 1 | import { NotionConstants } from '@nishans/constants'; 2 | import { IBlockMap } from '../../types'; 3 | 4 | /** 5 | * Returns an object with keys representing all the block types, and values containing a map of objects representing those block types 6 | */ 7 | export function createBlockMap () { 8 | const obj: IBlockMap = {} as any; 9 | NotionConstants.blockTypes().map((block_type) => (obj[block_type] = new Map())); 10 | return obj; 11 | } 12 | -------------------------------------------------------------------------------- /packages/core/libs/CreateMaps/createPageMap.ts: -------------------------------------------------------------------------------- 1 | import { IPageMap } from '../../types'; 2 | 3 | /** 4 | * Returns an object with keys representing all the page types, and values containing a map of objects representing those page types 5 | */ 6 | export function createPageMap () { 7 | return { 8 | page: new Map(), 9 | collection_view_page: new Map() 10 | } as IPageMap; 11 | } 12 | -------------------------------------------------------------------------------- /packages/core/libs/CreateMaps/createSchemaUnitMap.ts: -------------------------------------------------------------------------------- 1 | import { NotionConstants } from '@nishans/constants'; 2 | import { ISchemaUnitMap } from '../../types'; 3 | 4 | /** 5 | * Returns an object with keys representing all the schema_unit types, and values containing a map of objects representing those schema_unit types 6 | */ 7 | export function createSchemaUnitMap () { 8 | const obj: ISchemaUnitMap = {} as any; 9 | NotionConstants.schemaUnitTypes().map((schema_unit_type) => (obj[schema_unit_type] = new Map())); 10 | return obj; 11 | } 12 | -------------------------------------------------------------------------------- /packages/core/libs/CreateMaps/createViewMap.ts: -------------------------------------------------------------------------------- 1 | import { NotionConstants } from '@nishans/constants'; 2 | import { IViewMap } from '../../types'; 3 | 4 | /** 5 | * Returns an object with keys representing all the view types, and values containing a map of objects representing those view types 6 | */ 7 | export const createViewMap = () => { 8 | const obj: IViewMap = {} as any; 9 | NotionConstants.viewTypes().map((view_type) => (obj[view_type] = new Map())); 10 | return obj; 11 | }; 12 | -------------------------------------------------------------------------------- /packages/core/libs/CreateMaps/index.ts: -------------------------------------------------------------------------------- 1 | import { createBlockMap } from './createBlockMap'; 2 | import { createPageMap } from './createPageMap'; 3 | import { createSchemaUnitMap } from './createSchemaUnitMap'; 4 | import { createViewMap } from './createViewMap'; 5 | 6 | export const CreateMaps = { 7 | block: createBlockMap, 8 | view: createViewMap, 9 | schemaUnit: createSchemaUnitMap, 10 | page: createPageMap 11 | }; 12 | -------------------------------------------------------------------------------- /packages/core/libs/PopulateMap/index.ts: -------------------------------------------------------------------------------- 1 | import { populateBlockMap } from './populateBlockMap'; 2 | import { populateCollectionBlockMap } from './populateCollectionBlockMap'; 3 | import { populatePageMap } from './populatePageMap'; 4 | import { populateSchemaUnitMap } from './populateSchemaUnitMap'; 5 | import { populateViewMap } from './populateViewMap'; 6 | 7 | export const PopulateMap = { 8 | page: populatePageMap, 9 | view: populateViewMap, 10 | block: populateBlockMap, 11 | collectionBlock: populateCollectionBlockMap, 12 | schemaUnit: populateSchemaUnitMap 13 | }; 14 | -------------------------------------------------------------------------------- /packages/core/libs/PopulateMap/populateSchemaUnitMap.ts: -------------------------------------------------------------------------------- 1 | import { INotionFabricatorOptions } from '@nishans/fabricator'; 2 | import { TSchemaUnit } from '@nishans/types'; 3 | import { NotionCore } from '../'; 4 | import { ISchemaUnitMap } from '../../types'; 5 | 6 | export const populateSchemaUnitMap = ( 7 | id: string, 8 | schema_id: string, 9 | schema_unit: TSchemaUnit, 10 | options: INotionFabricatorOptions, 11 | schema_unit_map: ISchemaUnitMap 12 | ) => { 13 | const schema_unit_obj = new NotionCore.Api.SchemaUnit({ 14 | id, 15 | ...options, 16 | schema_id 17 | }); 18 | schema_unit_map[schema_unit.type].set(schema_id, schema_unit_obj); 19 | schema_unit_map[schema_unit.type].set(schema_unit.name, schema_unit_obj); 20 | }; 21 | -------------------------------------------------------------------------------- /packages/core/libs/index.ts: -------------------------------------------------------------------------------- 1 | export * from '../types'; 2 | import { CoreApi } from './Api'; 3 | import { createBlockClass } from './createBlockClass'; 4 | import { CreateMaps } from './CreateMaps'; 5 | import { PopulateMap } from './PopulateMap'; 6 | 7 | export const NotionCore = { 8 | Api: CoreApi, 9 | createBlockClass, 10 | PopulateMap, 11 | CreateMaps 12 | }; 13 | -------------------------------------------------------------------------------- /packages/core/libs/utils/applyMixins.ts: -------------------------------------------------------------------------------- 1 | export function applyMixins (derivedCtor: any, constructors: any[]) { 2 | constructors.forEach((baseCtor) => { 3 | Object.getOwnPropertyNames(baseCtor.prototype).forEach((name) => { 4 | Object.defineProperty( 5 | derivedCtor.prototype, 6 | name, 7 | Object.getOwnPropertyDescriptor(baseCtor.prototype, name) || Object.create(null) 8 | ); 9 | }); 10 | }); 11 | } 12 | -------------------------------------------------------------------------------- /packages/core/libs/utils/index.ts: -------------------------------------------------------------------------------- 1 | export * from './applyMixins'; 2 | export * from './createSpaceIterateData'; 3 | export * from './transformToMultiple'; 4 | -------------------------------------------------------------------------------- /packages/core/libs/utils/transformToMultiple.ts: -------------------------------------------------------------------------------- 1 | import { FilterType, FilterTypes, UpdateType, UpdateTypes } from "@nishans/traverser"; 2 | 3 | /** 4 | * Transforms the parameter that is suitable to be used in a multiple=true Nishan method 5 | * @param arg The argument to transform 6 | */ 7 | export function transformToMultiple (arg?: FilterType): FilterTypes; 8 | export function transformToMultiple (arg?: UpdateType): UpdateTypes; 9 | export function transformToMultiple ( 10 | arg?: UpdateType | FilterType 11 | ): FilterTypes | UpdateTypes { 12 | return typeof arg === 'string' ? [ arg ] : (Array.isArray(arg) ? [arg] : arg ?? (() => true)); 13 | } 14 | -------------------------------------------------------------------------------- /packages/core/tests/Api/View/BoardView.test.ts: -------------------------------------------------------------------------------- 1 | import { NotionCore } from '../../../libs'; 2 | import { default_nishan_arg } from '../../utils'; 3 | 4 | afterEach(() => { 5 | jest.restoreAllMocks(); 6 | }); 7 | 8 | it(`NotionCore.Api.BoardView`, () => { 9 | new NotionCore.Api.BoardView(default_nishan_arg); 10 | }); 11 | -------------------------------------------------------------------------------- /packages/core/tests/Api/View/CalendarView.test.ts: -------------------------------------------------------------------------------- 1 | import { NotionCore } from '../../../libs'; 2 | import { default_nishan_arg } from '../../utils'; 3 | 4 | afterEach(() => { 5 | jest.restoreAllMocks(); 6 | }); 7 | 8 | it(`NotionCore.Api.CalendarView`, () => { 9 | new NotionCore.Api.CalendarView(default_nishan_arg); 10 | }); 11 | -------------------------------------------------------------------------------- /packages/core/tests/Api/View/GalleryView.test.ts: -------------------------------------------------------------------------------- 1 | import { NotionCore } from '../../../libs'; 2 | import { default_nishan_arg } from '../../utils'; 3 | 4 | afterEach(() => { 5 | jest.restoreAllMocks(); 6 | }); 7 | 8 | it(`NotionCore.Api.GalleryView`, () => { 9 | new NotionCore.Api.GalleryView(default_nishan_arg); 10 | }); 11 | -------------------------------------------------------------------------------- /packages/core/tests/Api/View/ListView.test.ts: -------------------------------------------------------------------------------- 1 | import { NotionCore } from '../../../libs'; 2 | import { default_nishan_arg } from '../../utils'; 3 | 4 | afterEach(() => { 5 | jest.restoreAllMocks(); 6 | }); 7 | 8 | it(`NotionCore.Api.ListView`, () => { 9 | new NotionCore.Api.ListView(default_nishan_arg); 10 | }); 11 | -------------------------------------------------------------------------------- /packages/core/tests/Api/View/TableView.test.ts: -------------------------------------------------------------------------------- 1 | import { NotionCore } from '../../../libs'; 2 | import { default_nishan_arg } from '../../utils'; 3 | 4 | afterEach(() => { 5 | jest.restoreAllMocks(); 6 | }); 7 | 8 | it(`NotionCore.Api.TableView`, () => { 9 | new NotionCore.Api.TableView(default_nishan_arg); 10 | }); 11 | -------------------------------------------------------------------------------- /packages/core/tests/Api/View/TimelineView.test.ts: -------------------------------------------------------------------------------- 1 | import { NotionCore } from '../../../libs'; 2 | import { default_nishan_arg } from '../../utils'; 3 | 4 | afterEach(() => { 5 | jest.restoreAllMocks(); 6 | }); 7 | 8 | it(`TimelineView`, () => { 9 | new NotionCore.Api.TimelineView(default_nishan_arg); 10 | }); 11 | -------------------------------------------------------------------------------- /packages/core/tests/Api/View/utils.ts: -------------------------------------------------------------------------------- 1 | export const tas = { 2 | property: 'title', 3 | direction: 'ascending' 4 | }; 5 | 6 | export const txas = { 7 | property: 'text', 8 | direction: 'ascending' 9 | }; 10 | -------------------------------------------------------------------------------- /packages/core/tests/CreateMaps/createBlockMap.test.ts: -------------------------------------------------------------------------------- 1 | import { NotionConstants } from '@nishans/constants'; 2 | import { NotionCore } from '../../libs'; 3 | 4 | const block_map = NotionCore.CreateMaps.block(); 5 | 6 | it(`Should contain correct keys and value`, () => { 7 | NotionConstants.blockTypes().forEach((block_map_key) => expect(block_map[block_map_key] instanceof Map).toBe(true)); 8 | }); 9 | -------------------------------------------------------------------------------- /packages/core/tests/CreateMaps/createPageMap.test.ts: -------------------------------------------------------------------------------- 1 | import { IPageMap, NotionCore } from '../../libs'; 2 | 3 | const page_map_keys: (keyof IPageMap)[] = [ 'page', 'collection_view_page' ]; 4 | 5 | const page_map = NotionCore.CreateMaps.page(); 6 | it(`Should contain correct keys and value`, () => { 7 | page_map_keys.forEach((page_map_key) => expect(page_map[page_map_key] instanceof Map).toBe(true)); 8 | }); 9 | -------------------------------------------------------------------------------- /packages/core/tests/CreateMaps/createSchemaUnitMap.test.ts: -------------------------------------------------------------------------------- 1 | import { NotionConstants } from '@nishans/constants'; 2 | import { NotionCore } from '../../libs'; 3 | 4 | const schema_unit_map = NotionCore.CreateMaps.schemaUnit(); 5 | 6 | it(`Should contain correct keys and value`, () => { 7 | NotionConstants.schemaUnitTypes().forEach((schema_unit_map_key) => 8 | expect(schema_unit_map[schema_unit_map_key] instanceof Map).toBe(true) 9 | ); 10 | }); 11 | -------------------------------------------------------------------------------- /packages/core/tests/CreateMaps/createViewMap.test.ts: -------------------------------------------------------------------------------- 1 | import { NotionConstants } from '@nishans/constants'; 2 | import { NotionCore } from '../../libs'; 3 | 4 | const view_map = NotionCore.CreateMaps.view(); 5 | 6 | it(`Should contain correct keys and value`, () => { 7 | NotionConstants.viewTypes().forEach((view_map_key) => expect(view_map[view_map_key] instanceof Map).toBe(true)); 8 | }); 9 | -------------------------------------------------------------------------------- /packages/core/tests/PopulateMap/populateViewMap.test.ts: -------------------------------------------------------------------------------- 1 | import { NotionCache } from '@nishans/cache'; 2 | import { NotionCore } from '../../libs'; 3 | import { default_nishan_arg } from '../utils'; 4 | 5 | afterEach(() => { 6 | jest.restoreAllMocks(); 7 | }); 8 | 9 | it('PopulateMap.view', () => { 10 | const view_map = NotionCore.CreateMaps.view(); 11 | 12 | const cache = NotionCache.createDefaultCache(); 13 | 14 | NotionCore.PopulateMap.view( 15 | { name: 'Board', type: 'board', id: 'view_1' } as any, 16 | { 17 | ...default_nishan_arg, 18 | cache 19 | }, 20 | view_map 21 | ); 22 | 23 | expect(view_map.board.get('view_1')).not.toBeUndefined(); 24 | expect(view_map.board.get('Board')).not.toBeUndefined(); 25 | }); 26 | -------------------------------------------------------------------------------- /packages/core/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.shared.json", 3 | "include": [ 4 | "./libs/index.ts", 5 | "./experiment", 6 | "./examples" 7 | ], 8 | "compilerOptions": { 9 | "outDir": "./dist", 10 | "rootDir": "./", 11 | }, 12 | } -------------------------------------------------------------------------------- /packages/core/types/index.ts: -------------------------------------------------------------------------------- 1 | export * from './block'; 2 | export * from './maps'; 3 | export * from './nishan'; 4 | -------------------------------------------------------------------------------- /packages/core/types/nishan.ts: -------------------------------------------------------------------------------- 1 | import { INotionFabricatorOptions } from '@nishans/fabricator'; 2 | export interface INotionCoreOptions extends INotionFabricatorOptions { 3 | id: string; 4 | } 5 | -------------------------------------------------------------------------------- /packages/discord-bot/src/index.ts: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = discordBot; 4 | 5 | function discordBot() { 6 | // TODO 7 | } 8 | -------------------------------------------------------------------------------- /packages/discord-bot/src/types.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Devorein/Nishan/5c258d07d6a5a9ea45a3b44ec04eb19018f4deda/packages/discord-bot/src/types.ts -------------------------------------------------------------------------------- /packages/discord-bot/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "lib": [ 4 | "ESNext", 5 | "dom", 6 | ], 7 | "baseUrl": "./", 8 | "module": "commonjs", 9 | "moduleResolution": "node", 10 | "target": "ES2015", 11 | "strict": true, 12 | "esModuleInterop": true, 13 | "skipLibCheck": true, 14 | "forceConsistentCasingInFileNames": true, 15 | "outDir": "./dist", 16 | "watch": false, 17 | "declaration": true, 18 | "sourceMap": false, 19 | "noUnusedLocals": false, 20 | "incremental": false 21 | }, 22 | "include": [ 23 | "./src/index.ts", 24 | "experiment" 25 | ], 26 | "exclude": [ 27 | "./node_modules", 28 | ] 29 | } -------------------------------------------------------------------------------- /packages/discord-bot/utils/index.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Devorein/Nishan/5c258d07d6a5a9ea45a3b44ec04eb19018f4deda/packages/discord-bot/utils/index.ts -------------------------------------------------------------------------------- /packages/discourse/libs/Comments/index.ts: -------------------------------------------------------------------------------- 1 | import { createComments } from './createComments'; 2 | import { deleteComments } from './deleteComments'; 3 | import { getComments } from './getComments'; 4 | import { updateComments } from './updateComments'; 5 | 6 | export const NotionDiscourseComments = { 7 | create: createComments, 8 | update: updateComments, 9 | delete: deleteComments, 10 | get: getComments 11 | }; 12 | -------------------------------------------------------------------------------- /packages/discourse/libs/Discussions/index.ts: -------------------------------------------------------------------------------- 1 | import { createDiscussions } from './createDiscussions'; 2 | import { deleteDiscussions } from './deleteDiscussions'; 3 | import { getDiscussions } from './getDiscussions'; 4 | import { updateDiscussions } from './updateDiscussions'; 5 | 6 | export const NotionDiscourseDiscussions = { 7 | create: createDiscussions, 8 | update: updateDiscussions, 9 | delete: deleteDiscussions, 10 | get: getDiscussions 11 | }; 12 | -------------------------------------------------------------------------------- /packages/discourse/libs/index.ts: -------------------------------------------------------------------------------- 1 | import { NotionDiscourseComments } from './Comments'; 2 | import { NotionDiscourseDiscussions } from './Discussions'; 3 | 4 | export * from './types'; 5 | 6 | export const NotionDiscourse = { 7 | Discussions: NotionDiscourseDiscussions, 8 | Comments: NotionDiscourseComments 9 | }; 10 | -------------------------------------------------------------------------------- /packages/discourse/libs/types.ts: -------------------------------------------------------------------------------- 1 | import { IDiscussion, TTextFormat } from '@nishans/types'; 2 | 3 | export type ICommentCreateInput = { id?: string; text: TTextFormat }; 4 | export type ICommentUpdateInput = { text?: TTextFormat }; 5 | export type IDiscussionUpdateInput = Partial>; 6 | export type IDiscussionCreateInput = { 7 | context?: TTextFormat; 8 | id?: string; 9 | comments: ICommentCreateInput[]; 10 | resolved?: boolean; 11 | }; 12 | -------------------------------------------------------------------------------- /packages/discourse/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.shared.json", 3 | "include": [ 4 | "./libs/index.ts", 5 | "./experiment", 6 | "./examples" 7 | ], 8 | "compilerOptions": { 9 | "baseUrl": ".", 10 | "outDir": "./dist", 11 | "rootDir": "./", 12 | }, 13 | } -------------------------------------------------------------------------------- /packages/endpoints/libs/Request/createTransaction.ts: -------------------------------------------------------------------------------- 1 | import { INotionEndpoints, IOperation } from '@nishans/types'; 2 | import { v4 } from 'uuid'; 3 | 4 | /** 5 | * Create a transaction object suitable to be sent to the saveTransaction endpoint 6 | * @param spaceId The id of the workspace 7 | * @param operations The operations array to be added to the transaction 8 | */ 9 | export function createTransaction(spaceId: string, operations: IOperation[]) { 10 | return { 11 | requestId: v4(), 12 | transactions: [ 13 | { 14 | id: v4(), 15 | spaceId, 16 | operations 17 | } 18 | ] 19 | } as INotionEndpoints['saveTransactions']['payload']; 20 | } 21 | -------------------------------------------------------------------------------- /packages/endpoints/libs/Request/index.ts: -------------------------------------------------------------------------------- 1 | import { constructNotionHeaders } from './constructNotionHeaders'; 2 | import { createTransaction } from './createTransaction'; 3 | import { sendRequest } from './sendRequest'; 4 | 5 | export const NotionEndpointsRequest = { 6 | send: sendRequest, 7 | constructHeaders: constructNotionHeaders, 8 | createTransaction 9 | }; 10 | -------------------------------------------------------------------------------- /packages/endpoints/libs/index.ts: -------------------------------------------------------------------------------- 1 | export * from './types'; 2 | 3 | import { NotionEndpointsMutations } from './Mutations'; 4 | import { NotionEndpointsQueries } from './Queries'; 5 | import { NotionEndpointsRequest } from './Request'; 6 | 7 | export const NotionEndpoints = { 8 | Request: NotionEndpointsRequest, 9 | Mutations: NotionEndpointsMutations, 10 | Queries: NotionEndpointsQueries 11 | }; 12 | -------------------------------------------------------------------------------- /packages/endpoints/libs/types.ts: -------------------------------------------------------------------------------- 1 | import { TDataType } from '@nishans/types'; 2 | 3 | export type SyncRecordValuesTuple = [string, TDataType][]; 4 | 5 | export interface NotionHeaders { 6 | headers: { 7 | cookie: string; 8 | ['x-notion-active-user-header']: string; 9 | }; 10 | } 11 | 12 | export interface INotionEndpointsOptions { 13 | token: string; 14 | user_id: string; 15 | interval?: number; 16 | logger?: boolean; 17 | } 18 | -------------------------------------------------------------------------------- /packages/endpoints/tests/Request/createTransaction.test.ts: -------------------------------------------------------------------------------- 1 | import { NotionEndpoints } from '../../libs'; 2 | 3 | afterEach(() => { 4 | jest.restoreAllMocks(); 5 | }); 6 | 7 | it('createTransaction', () => { 8 | const transactions = NotionEndpoints.Request.createTransaction( 9 | 'space_id', 10 | [] 11 | ); 12 | const data = JSON.parse(JSON.stringify(transactions)); 13 | expect(data.transactions[0]).toEqual( 14 | expect.objectContaining({ 15 | id: expect.any(String), 16 | spaceId: 'space_id', 17 | operations: expect.any(Array) 18 | }) 19 | ); 20 | }); 21 | -------------------------------------------------------------------------------- /packages/endpoints/tests/Request/utils.ts: -------------------------------------------------------------------------------- 1 | export const notion_request_configs = { 2 | token: 'token', 3 | user_id: 'user_id', 4 | interval: 0 5 | }; 6 | -------------------------------------------------------------------------------- /packages/endpoints/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.shared.json", 3 | "include": [ 4 | "./libs/index.ts", 5 | "./experiment" 6 | ], 7 | "compilerOptions": { 8 | "outDir": "./dist", 9 | "rootDir": "./" 10 | } 11 | } -------------------------------------------------------------------------------- /packages/errors/libs/NonExistentData.ts: -------------------------------------------------------------------------------- 1 | import { TDataType } from '@nishans/types'; 2 | import colors from 'colors'; 3 | 4 | /** 5 | * Thrown when a data doesn't exist in cache or from a response 6 | */ 7 | export class NonExistentData extends Error { 8 | // An array of property types to be expected 9 | constructor (data_type: TDataType, id: string) { 10 | super(colors.bold.red(`${data_type}:${id} doesn't exist`)); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /packages/errors/libs/NonExistentSchemaUnitType.ts: -------------------------------------------------------------------------------- 1 | import { TSchemaUnitType } from '@nishans/types'; 2 | import colors from 'colors'; 3 | 4 | /** 5 | * A notion specific error class, that is thrown when a schema doesn't contain a specific type of property 6 | */ 7 | export class NonExistentSchemaUnitType extends Error { 8 | // An array of property types to be expected 9 | constructor (expected_types: TSchemaUnitType[]) { 10 | super(colors.bold.red(`Schema doesn't contain any property of type ${expected_types.join(' | ')}`)); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /packages/errors/libs/PreExistentValue.ts: -------------------------------------------------------------------------------- 1 | import colors from 'colors'; 2 | 3 | /** 4 | * Thrown when a new value is trying to be set when there is already a previous value 5 | */ 6 | export class PreExistentValue extends Error { 7 | /** 8 | * @param value_type The type of the value 9 | * @param value_for For what does the duplicate value exists 10 | * @param value_current Current value 11 | */ 12 | constructor (value_type: string, value_for: string, value_current: string) { 13 | super(colors.bold.red(`There is already a value for ${value_type} on ${value_for}, ${value_current}.`)); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /packages/errors/libs/SchemaDuplicatePropertyName.ts: -------------------------------------------------------------------------------- 1 | import colors from 'colors'; 2 | 3 | /** 4 | * Thrown when schema contains duplicate property name 5 | */ 6 | export class SchemaDuplicatePropertyName extends Error { 7 | /** 8 | * @param property_name The name of the duplicate property 9 | */ 10 | constructor (property_name: string) { 11 | super(colors.bold.red(`Schema already contains property with name ${property_name}.`)); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /packages/errors/libs/UnknownPropertyReference.ts: -------------------------------------------------------------------------------- 1 | import colors from 'colors'; 2 | 3 | /** 4 | * A notion specific error class, that is thrown when an unknown property, that doesn't exist in the schema is referenced 5 | */ 6 | export class UnknownPropertyReference extends Error { 7 | /** 8 | * 9 | * @param property The name of the property 10 | * @param path The path to the property 11 | */ 12 | constructor (property: string, path: string[]) { 13 | super(colors.bold.red(`Unknown property ${property} referenced in ${path.join('.')}`)); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /packages/errors/libs/UnsupportedDataType.ts: -------------------------------------------------------------------------------- 1 | import { TDataType } from '@nishans/types'; 2 | import colors from 'colors'; 3 | 4 | /** 5 | * A notion specific error class, that is thrown when the data type doesn't match the supported types 6 | */ 7 | export class UnsupportedDataType extends Error { 8 | /** 9 | * @param given_data_type passed data type 10 | * @param supported_data_types The supported data type of the property 11 | */ 12 | constructor (given_data_type: string, supported_data_types: TDataType[]) { 13 | super( 14 | colors.bold.red( 15 | `Data type is not of the supported types\nGiven type: ${given_data_type}\nSupported types: ${supported_data_types.join( 16 | ' | ' 17 | )}` 18 | ) 19 | ); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /packages/errors/libs/UnsupportedFunctionName.ts: -------------------------------------------------------------------------------- 1 | import { TFunctionName } from '@nishans/types'; 2 | import colors from 'colors'; 3 | 4 | /** 5 | * A notion specific error class, that is thrown when the data type doesn't match the supported types 6 | */ 7 | export class UnsupportedFunctionName extends Error { 8 | /** 9 | * @param given_function passed function name 10 | * @param supported_functions The supported function names 11 | */ 12 | constructor (given_function: string, supported_functions: TFunctionName[]) { 13 | super( 14 | colors.bold.red( 15 | `Function is not supported.\nGiven function: ${given_function}\nSupported functions: ${supported_functions.join( 16 | ' | ' 17 | )}` 18 | ) 19 | ); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /packages/errors/tests/ChildIndexOutofBoundError.test.ts: -------------------------------------------------------------------------------- 1 | import colors from 'colors'; 2 | import { NotionErrors } from '../libs'; 3 | 4 | it(`ChildIndexOutofBoundError`, () => { 5 | expect(new NotionErrors.child_index_out_of_bound(3, 2, 'data').message).toBe( 6 | colors.bold.red(`Parent doesn't contain any children at index 3.\nParent child container data contains 2 items.`) 7 | ); 8 | }); 9 | -------------------------------------------------------------------------------- /packages/errors/tests/FunctionArgumentLengthMismatch.test.ts: -------------------------------------------------------------------------------- 1 | import colors from 'colors'; 2 | import { NotionErrors } from '../libs'; 3 | 4 | it(`FunctionArgumentLengthMismatch`, () => { 5 | expect(new NotionErrors.function_argument_length_mismatch(2, [ 3 ], 'max').message).toBe( 6 | colors.bold.red(`Function max takes 3 arguments, given 2`) 7 | ); 8 | }); 9 | -------------------------------------------------------------------------------- /packages/errors/tests/FunctionArgumentTypeMismatch.test.ts: -------------------------------------------------------------------------------- 1 | import colors from 'colors'; 2 | import { NotionErrors } from '../libs'; 3 | 4 | it(`FunctionArgumentTypeMismatch`, () => { 5 | expect(new NotionErrors.function_argument_type_mismatch('number', 1, 'max').message).toBe( 6 | colors.bold.red(`Argument of type number can't be used as argument 1 for function max.`) 7 | ); 8 | }); 9 | -------------------------------------------------------------------------------- /packages/errors/tests/NonExistentDataError.test.ts: -------------------------------------------------------------------------------- 1 | import colors from 'colors'; 2 | import { NotionErrors } from '../libs'; 3 | 4 | it(`NonExistentDataError`, () => { 5 | expect(new NotionErrors.non_existent_data('collection', '123').message).toBe( 6 | colors.bold.red(`collection:123 doesn't exist`) 7 | ); 8 | }); 9 | -------------------------------------------------------------------------------- /packages/errors/tests/NonExistentSchemaUnitTypeError.test.ts: -------------------------------------------------------------------------------- 1 | import colors from 'colors'; 2 | import { NotionErrors } from '../libs'; 3 | 4 | it(`NonExistentSchemaUnitTypeError`, () => { 5 | expect(new NotionErrors.non_existent_schema_unit_type([ 'checkbox', 'title' ]).message).toBe( 6 | colors.bold.red(`Schema doesn't contain any property of type checkbox | title`) 7 | ); 8 | }); 9 | -------------------------------------------------------------------------------- /packages/errors/tests/PreExistentValueError.test.ts: -------------------------------------------------------------------------------- 1 | import colors from 'colors'; 2 | import { NotionErrors } from '../libs'; 3 | 4 | it(`PreExistentValueError`, () => { 5 | expect(new NotionErrors.pre_existent_value('value_type', 'value_for', 'value_current').message).toBe( 6 | colors.bold.red(`There is already a value for value_type on value_for, value_current.`) 7 | ); 8 | }); 9 | -------------------------------------------------------------------------------- /packages/errors/tests/SchemaDuplicatePropertyNameError.test.ts: -------------------------------------------------------------------------------- 1 | import colors from 'colors'; 2 | import { NotionErrors } from '../libs'; 3 | 4 | it(`SchemaDuplicatePropertyNameError`, () => { 5 | expect(new NotionErrors.schema_duplicate_property_name('Name').message).toBe( 6 | colors.bold.red(`Schema already contains property with name Name.`) 7 | ); 8 | }); 9 | -------------------------------------------------------------------------------- /packages/errors/tests/UnknownPropertyReferenceError.test.ts: -------------------------------------------------------------------------------- 1 | import colors from 'colors'; 2 | import { NotionErrors } from '../libs'; 3 | 4 | it(`UnknownPropertyReferenceError`, () => { 5 | expect(new NotionErrors.unknown_property_reference('Name', [ 'arg', 'name' ]).message).toBe( 6 | colors.bold.red(`Unknown property Name referenced in arg.name`) 7 | ); 8 | }); 9 | -------------------------------------------------------------------------------- /packages/errors/tests/UnsupportedBlockTypeError.test.ts: -------------------------------------------------------------------------------- 1 | import colors from 'colors'; 2 | import { NotionErrors } from '../libs'; 3 | 4 | it(`UnsupportedBlockTypeError`, () => { 5 | expect(new NotionErrors.unsupported_block_type('notion_user', [ 'to_do', 'header' ]).message).toBe( 6 | colors.bold.red( 7 | `Block type is not of the supported types\nGiven type: notion_user\nSupported types: to_do | header` 8 | ) 9 | ); 10 | }); 11 | -------------------------------------------------------------------------------- /packages/errors/tests/UnsupportedDataTypeError.test.ts: -------------------------------------------------------------------------------- 1 | import colors from 'colors'; 2 | import { NotionErrors } from '../libs'; 3 | 4 | it(`UnsupportedDataTypeError`, () => { 5 | expect(new NotionErrors.unsupported_data_type('notion_user', [ 'block', 'collection' ]).message).toBe( 6 | colors.bold.red( 7 | `Data type is not of the supported types\nGiven type: notion_user\nSupported types: block | collection` 8 | ) 9 | ); 10 | }); 11 | -------------------------------------------------------------------------------- /packages/errors/tests/UnsupportedFunctionName.test.ts: -------------------------------------------------------------------------------- 1 | import colors from 'colors'; 2 | import { NotionErrors } from '../libs'; 3 | 4 | it(`UnsupportedFunctionNameError`, () => { 5 | expect(new NotionErrors.unsupported_function_name('notion_user', [ 'max', 'min' ]).message).toBe( 6 | colors.bold.red(`Function is not supported.\nGiven function: notion_user\nSupported functions: max | min`) 7 | ); 8 | }); 9 | -------------------------------------------------------------------------------- /packages/errors/tests/UnsupportedPropertyTypeError.test.ts: -------------------------------------------------------------------------------- 1 | import colors from 'colors'; 2 | import { NotionErrors } from '../libs'; 3 | 4 | it(`UnsupportedPropertyTypeError`, () => { 5 | expect( 6 | new NotionErrors.unsupported_property_type('Name', [ 'arg', 'name' ], 'text', [ 'checkbox', 'number' ]).message 7 | ).toBe( 8 | colors.bold.red( 9 | `Property Name referenced in arg.name is not of the supported types\nGiven type: text\nSupported types: checkbox | number` 10 | ) 11 | ); 12 | }); 13 | -------------------------------------------------------------------------------- /packages/errors/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.shared.json", 3 | "include": [ 4 | "./libs/index.ts", 5 | "./experiment" 6 | ], 7 | "compilerOptions": { 8 | "outDir": "./dist", 9 | "rootDir": "./" 10 | } 11 | } -------------------------------------------------------------------------------- /packages/extract/libs/collection.ts: -------------------------------------------------------------------------------- 1 | import { ICollection } from '@nishans/types'; 2 | import { CollectionExtracted } from '.'; 3 | 4 | export const extractCollectionData = ({ 5 | description, 6 | name, 7 | icon, 8 | cover, 9 | schema 10 | }: ICollection | CollectionExtracted) => { 11 | return { 12 | name, 13 | icon, 14 | cover, 15 | description, 16 | schema 17 | } as CollectionExtracted; 18 | }; 19 | -------------------------------------------------------------------------------- /packages/extract/libs/index.ts: -------------------------------------------------------------------------------- 1 | import { extractCollectionData } from './collection'; 2 | import { extractPagesData } from './pages'; 3 | import { extractViewsData } from './views'; 4 | 5 | export const NotionExtract = { 6 | pages: extractPagesData, 7 | template_pages: extractPagesData, 8 | collection: extractCollectionData, 9 | views: extractViewsData 10 | }; 11 | 12 | export * from './types'; 13 | -------------------------------------------------------------------------------- /packages/extract/libs/pages.ts: -------------------------------------------------------------------------------- 1 | import { IPage } from '@nishans/types'; 2 | import { PageExtracted } from './types'; 3 | 4 | export const extractPagesData = (row_pages: (IPage | PageExtracted)[]) => 5 | row_pages.map((page) => ({ 6 | is_template: page.is_template ?? false, 7 | properties: page.properties, 8 | format: page.format 9 | })); 10 | -------------------------------------------------------------------------------- /packages/extract/libs/types.ts: -------------------------------------------------------------------------------- 1 | import { ICollection, IPage, TView } from '@nishans/types'; 2 | 3 | export type CollectionExtracted = Pick; 4 | export type TViewExtracted = Pick; 5 | export type PageExtracted = Pick; 6 | -------------------------------------------------------------------------------- /packages/extract/libs/views.ts: -------------------------------------------------------------------------------- 1 | import { TView } from '@nishans/types'; 2 | import { TViewExtracted } from './'; 3 | 4 | export const extractViewsData = (views_data: (TView | TViewExtracted)[]) => { 5 | return views_data.map((view_data) => { 6 | return { 7 | type: view_data.type, 8 | name: view_data.name, 9 | format: view_data.format, 10 | query2: view_data.query2 11 | }; 12 | }); 13 | }; 14 | -------------------------------------------------------------------------------- /packages/extract/tests/collection.test.ts: -------------------------------------------------------------------------------- 1 | import { CollectionExtracted, NotionExtract } from '../libs'; 2 | 3 | it(`extract collection data`, () => { 4 | const extracted_collection_data: CollectionExtracted = { 5 | name: [ [ 'Name' ] ], 6 | schema: {}, 7 | cover: '', 8 | description: [ [ '' ] ], 9 | icon: '' 10 | }; 11 | 12 | expect(NotionExtract.collection({ ...extracted_collection_data, extra: 'data' } as any)).toStrictEqual( 13 | extracted_collection_data 14 | ); 15 | }); 16 | -------------------------------------------------------------------------------- /packages/extract/tests/views.test.ts: -------------------------------------------------------------------------------- 1 | import { NotionExtract, TViewExtracted } from '../libs'; 2 | 3 | it(`extract views data`, () => { 4 | const extracted_views_data: TViewExtracted = { 5 | format: {} as any, 6 | name: 'View', 7 | type: 'board', 8 | query2: {} 9 | }; 10 | 11 | expect(NotionExtract.views([ { ...extracted_views_data, extra: 'data' } as any ])).toStrictEqual([ 12 | extracted_views_data 13 | ]); 14 | }); 15 | -------------------------------------------------------------------------------- /packages/extract/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.shared.json", 3 | "include": [ 4 | "./libs/index.ts", 5 | "./experiment", 6 | "./examples" 7 | ], 8 | "compilerOptions": { 9 | "outDir": "./dist", 10 | "rootDir": "./", 11 | }, 12 | } -------------------------------------------------------------------------------- /packages/fabricator/libs/CreateData/SchemaUnit/index.ts: -------------------------------------------------------------------------------- 1 | import { relation } from './relation'; 2 | import { rollup } from './rollup'; 3 | 4 | export const CreateSchemaUnit = { 5 | relation, 6 | rollup 7 | }; 8 | -------------------------------------------------------------------------------- /packages/fabricator/libs/CreateData/index.ts: -------------------------------------------------------------------------------- 1 | import { collection } from './collection'; 2 | import { contents } from './contents'; 3 | import { schema } from './schema'; 4 | import { CreateSchemaUnit } from './SchemaUnit'; 5 | import { views } from './views'; 6 | 7 | export const CreateData = { 8 | views, 9 | collection, 10 | contents, 11 | schema, 12 | SchemaUnit: CreateSchemaUnit 13 | }; 14 | -------------------------------------------------------------------------------- /packages/fabricator/libs/CreateData/utils/index.ts: -------------------------------------------------------------------------------- 1 | export * from './executeOperationAndStoreInCache'; 2 | export * from './generateViewData'; 3 | export * from './populatePermissions'; 4 | -------------------------------------------------------------------------------- /packages/fabricator/libs/CreateData/utils/populatePermissions.ts: -------------------------------------------------------------------------------- 1 | import { IPermission } from '@nishans/types'; 2 | 3 | /** 4 | * Creates and returns a permission object that is either user or space available 5 | * @param user_id Id of the user attached with the permission 6 | * @param is_private Indicates whether the page is available to all space members or only a single user 7 | * @returns A permission object based on the passed parameter 8 | */ 9 | export function populatePermissions (user_id: string, is_private?: boolean): IPermission { 10 | return { type: is_private ? 'user_permission' : 'space_permission', role: 'editor', user_id: user_id }; 11 | } 12 | -------------------------------------------------------------------------------- /packages/fabricator/libs/PopulateViewData/format/index.ts: -------------------------------------------------------------------------------- 1 | import { populateViewFormat } from './format'; 2 | import { populateViewFormatProperties } from './properties'; 3 | 4 | export const PopulateViewFormatData = { 5 | format: populateViewFormat, 6 | properties: populateViewFormatProperties 7 | }; 8 | -------------------------------------------------------------------------------- /packages/fabricator/libs/PopulateViewData/format/utils/index.ts: -------------------------------------------------------------------------------- 1 | export * from './tableFormat'; 2 | -------------------------------------------------------------------------------- /packages/fabricator/libs/PopulateViewData/index.ts: -------------------------------------------------------------------------------- 1 | import { PopulateViewFormatData } from './format'; 2 | import { PopulateViewQuery2Data } from './query2'; 3 | 4 | export const PopulateViewData = { 5 | query2: PopulateViewQuery2Data, 6 | format: PopulateViewFormatData 7 | }; 8 | -------------------------------------------------------------------------------- /packages/fabricator/libs/PopulateViewData/query2/index.ts: -------------------------------------------------------------------------------- 1 | import { populateViewQuery2Aggregation } from './aggregation'; 2 | import { populateViewQuery2Filters } from './filters'; 3 | import { populateViewQuery2 } from './query2'; 4 | import { populateViewQuery2Sort } from './sort'; 5 | 6 | export const PopulateViewQuery2Data = { 7 | sort: populateViewQuery2Sort, 8 | filters: populateViewQuery2Filters, 9 | query2: populateViewQuery2, 10 | aggregation: populateViewQuery2Aggregation 11 | }; 12 | -------------------------------------------------------------------------------- /packages/fabricator/libs/PopulateViewMaps/index.ts: -------------------------------------------------------------------------------- 1 | import { aggregations } from './aggregations'; 2 | import { filters } from './filters'; 3 | import { properties } from './properties'; 4 | import { sorts } from './sorts'; 5 | 6 | export const PopulateViewMaps = { 7 | properties, 8 | sorts, 9 | filters, 10 | aggregations 11 | }; 12 | -------------------------------------------------------------------------------- /packages/fabricator/libs/index.ts: -------------------------------------------------------------------------------- 1 | export * from '../types'; 2 | import { CreateData } from './CreateData'; 3 | import { PopulateViewData } from './PopulateViewData'; 4 | import { PopulateViewMaps } from './PopulateViewMaps'; 5 | 6 | export const NotionFabricator = { 7 | PopulateViewMaps, 8 | CreateData, 9 | PopulateViewData 10 | }; 11 | -------------------------------------------------------------------------------- /packages/fabricator/tests/PopulateViewMaps/aggregations.test.ts: -------------------------------------------------------------------------------- 1 | import { NotionFabricator } from '../../libs'; 2 | import { schema, tsmu } from './utils'; 3 | 4 | const aggregation = { 5 | property: 'title', 6 | aggregator: 'count' 7 | }; 8 | 9 | it(`Should create correct schema map`, () => { 10 | const [ aggregations_map ] = NotionFabricator.PopulateViewMaps.aggregations( 11 | { 12 | query2: { 13 | aggregations: [ aggregation ] 14 | } 15 | } as any, 16 | schema 17 | ); 18 | 19 | expect(Array.from(aggregations_map.entries())).toStrictEqual([ 20 | [ 21 | 'Title', 22 | { 23 | ...tsmu, 24 | aggregation 25 | } 26 | ] 27 | ]); 28 | }); 29 | -------------------------------------------------------------------------------- /packages/fabricator/tests/PopulateViewMaps/properties.test.ts: -------------------------------------------------------------------------------- 1 | import { NotionFabricator } from '../../libs'; 2 | import { schema, tsmu } from './utils'; 3 | 4 | const format_property = { 5 | width: 150, 6 | visible: false, 7 | property: 'title' 8 | }; 9 | 10 | it(`Should create correct schema map`, () => { 11 | const [ format_map ] = NotionFabricator.PopulateViewMaps.properties( 12 | { 13 | type: 'table', 14 | format: { 15 | table_properties: [ format_property ] 16 | } 17 | } as any, 18 | schema 19 | ); 20 | 21 | expect(Array.from(format_map.entries())).toStrictEqual([ 22 | [ 23 | 'Title', 24 | { 25 | ...tsmu, 26 | format: format_property 27 | } 28 | ] 29 | ]); 30 | }); 31 | -------------------------------------------------------------------------------- /packages/fabricator/tests/PopulateViewMaps/sorts.test.ts: -------------------------------------------------------------------------------- 1 | import { NotionFabricator } from '../../libs'; 2 | import { schema, tsmu } from './utils'; 3 | 4 | const sort = { 5 | property: 'title', 6 | direction: 'ascending' 7 | }; 8 | 9 | it(`Should create correct schema map`, () => { 10 | const [ sorts_map ] = NotionFabricator.PopulateViewMaps.sorts( 11 | { 12 | query2: { 13 | sort: [ sort ] 14 | } 15 | } as any, 16 | schema 17 | ); 18 | 19 | expect(Array.from(sorts_map.entries())).toStrictEqual([ 20 | [ 21 | 'Title', 22 | { 23 | ...tsmu, 24 | sort 25 | } 26 | ] 27 | ]); 28 | }); 29 | -------------------------------------------------------------------------------- /packages/fabricator/tests/PopulateViewMaps/utils.ts: -------------------------------------------------------------------------------- 1 | import { Schema } from '@nishans/types'; 2 | 3 | export const schema: Schema = { 4 | title: { 5 | type: 'title', 6 | name: 'Title' 7 | }, 8 | number: { 9 | type: 'number', 10 | name: 'Number' 11 | }, 12 | text: { 13 | type: 'text', 14 | name: 'Text' 15 | } 16 | }; 17 | 18 | // title schema map unit 19 | export const tsmu = { 20 | schema_id: 'title', 21 | name: 'Title', 22 | type: 'title' 23 | }; 24 | -------------------------------------------------------------------------------- /packages/fabricator/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.shared.json", 3 | "include": [ 4 | "./libs/index.ts", 5 | "./experiment" 6 | ], 7 | "compilerOptions": { 8 | "baseUrl": "./libs", 9 | "outDir": "./dist", 10 | "rootDir": "./", 11 | "paths": { 12 | "@tests": [ 13 | "../../../utils/tests" 14 | ] 15 | } 16 | }, 17 | } -------------------------------------------------------------------------------- /packages/fabricator/types/index.ts: -------------------------------------------------------------------------------- 1 | export * from './aggregations'; 2 | export * from './block'; 3 | export * from './filter'; 4 | export * from './schema'; 5 | export * from './sort'; 6 | export * from './utils'; 7 | export * from './view'; 8 | -------------------------------------------------------------------------------- /packages/fabricator/types/sort.ts: -------------------------------------------------------------------------------- 1 | import { TSortValue } from '@nishans/types'; 2 | 3 | export type TSortCreateInput = [string, TSortValue, number] | [string, TSortValue]; 4 | export type TSortUpdateInput = TSortValue | number | [TSortValue, number]; 5 | -------------------------------------------------------------------------------- /packages/fabricator/types/utils.ts: -------------------------------------------------------------------------------- 1 | import { INotionCacheOptions } from '@nishans/cache'; 2 | import { INotionOperationOptions } from '@nishans/operations'; 3 | import { TTextFormat } from '@nishans/types'; 4 | 5 | export type TMethodType = 'CREATE' | 'READ' | 'UPDATE' | 'DELETE'; 6 | 7 | export interface ParentCollectionData { 8 | parent_collection_id: string; 9 | name: TTextFormat; 10 | parent_relation_schema_unit_id: string; 11 | } 12 | 13 | export interface INotionFabricatorOptions extends INotionOperationOptions, INotionCacheOptions {} 14 | -------------------------------------------------------------------------------- /packages/graphql/libs/Resolvers/query.ts: -------------------------------------------------------------------------------- 1 | import { INotionCacheOptions, NotionCache } from '@nishans/cache'; 2 | 3 | export const NotionGraphqlQueryResolvers = { 4 | space: async (_: any, args: { id: string }, ctx: INotionCacheOptions) => 5 | await NotionCache.fetchDataOrReturnCached('space', args.id, ctx), 6 | page: async (_: any, args: { id: string }, ctx: INotionCacheOptions) => 7 | await NotionCache.fetchDataOrReturnCached('block', args.id, ctx), 8 | block: async (_: any, args: { id: string }, ctx: INotionCacheOptions) => 9 | await NotionCache.fetchDataOrReturnCached('block', args.id, ctx) 10 | }; 11 | -------------------------------------------------------------------------------- /packages/graphql/libs/Resolvers/space.ts: -------------------------------------------------------------------------------- 1 | import { NotionCache } from '@nishans/cache'; 2 | import { INotionCoreOptions } from '@nishans/core'; 3 | import { ISpace } from '@nishans/types'; 4 | import { NotionGraphqlNotionUserResolvers } from './utils'; 5 | 6 | export const NotionGraphqlSpaceResolver = { 7 | pages: async (space: ISpace, _: any, ctx: INotionCoreOptions) => { 8 | if (!ctx.cache_init_tracker.space.get(space.id)) { 9 | await NotionCache.initializeCacheForSpecificData(space.id, 'space', ctx); 10 | ctx.cache_init_tracker.space.set(space.id, true); 11 | } 12 | return space.pages.map((id) => ctx.cache.block.get(id)); 13 | }, 14 | ...NotionGraphqlNotionUserResolvers 15 | }; 16 | -------------------------------------------------------------------------------- /packages/graphql/libs/Resolvers/utils/commonBlockResolvers.ts: -------------------------------------------------------------------------------- 1 | import { INotionCacheOptions, NotionCache } from '@nishans/cache'; 2 | import { TBlock } from '@nishans/types'; 3 | import { NotionGraphqlNotionUserResolvers } from './notionUserResolvers'; 4 | 5 | export const NotionGraphqlCommonBlockResolvers = { 6 | parent: async ({ parent_id, parent_table }: TBlock, _: any, ctx: INotionCacheOptions) => 7 | await NotionCache.fetchDataOrReturnCached(parent_table, parent_id, ctx), 8 | space: async ({ space_id }: TBlock, _: any, ctx: INotionCacheOptions) => 9 | await NotionCache.fetchDataOrReturnCached('space', space_id, ctx), 10 | ...NotionGraphqlNotionUserResolvers 11 | }; 12 | -------------------------------------------------------------------------------- /packages/graphql/libs/Resolvers/utils/getBlockResolveType.ts: -------------------------------------------------------------------------------- 1 | import { TBlock } from '@nishans/types'; 2 | 3 | export function getBlockResolveType (obj: TBlock) { 4 | if (obj.type === 'collection_view') return 'CollectionView'; 5 | else if (obj.type === 'collection_view_page') return 'CollectionViewPage'; 6 | else if (obj.type === 'page') return 'Page'; 7 | } 8 | -------------------------------------------------------------------------------- /packages/graphql/libs/Resolvers/utils/getParentResolveType.ts: -------------------------------------------------------------------------------- 1 | import { ICollectionViewPage, IPage, ISpace, TParentType } from '@nishans/types'; 2 | 3 | export function getParentResolveType (obj: TParentType) { 4 | if ((obj as IPage).type === 'page') return 'Page'; 5 | else if ((obj as ICollectionViewPage).type === 'collection_view_page') return 'CollectionViewPage'; 6 | else if ((obj as ISpace).pages) return 'Space'; 7 | } 8 | -------------------------------------------------------------------------------- /packages/graphql/libs/Resolvers/utils/index.ts: -------------------------------------------------------------------------------- 1 | export * from './commonBlockResolvers'; 2 | export * from './getBlockResolveType'; 3 | export * from './getParentResolveType'; 4 | export * from './notionUserResolvers'; 5 | -------------------------------------------------------------------------------- /packages/graphql/libs/Resolvers/utils/notionUserResolvers.ts: -------------------------------------------------------------------------------- 1 | import { INotionCacheOptions, NotionCache } from '@nishans/cache'; 2 | import { TBlock } from '@nishans/types'; 3 | 4 | export const NotionGraphqlNotionUserResolvers = { 5 | last_edited_by: async ({ last_edited_by_id }: TBlock, _: any, ctx: INotionCacheOptions) => 6 | await NotionCache.fetchDataOrReturnCached('notion_user', last_edited_by_id, ctx), 7 | created_by: async ({ created_by_id }: TBlock, _: any, ctx: INotionCacheOptions) => 8 | await NotionCache.fetchDataOrReturnCached('notion_user', created_by_id, ctx) 9 | }; 10 | -------------------------------------------------------------------------------- /packages/graphql/libs/index.ts: -------------------------------------------------------------------------------- 1 | export * from './Resolvers/utils/getBlockResolveType'; 2 | 3 | import { NotionGraphqlResolvers } from './Resolvers'; 4 | import { server } from './server'; 5 | import { NotionGraphqlTypedefs } from './typedefs'; 6 | 7 | export const NotionGraphql = { 8 | server, 9 | Resolvers: NotionGraphqlResolvers, 10 | typedefs: NotionGraphqlTypedefs 11 | }; 12 | -------------------------------------------------------------------------------- /packages/graphql/libs/server.ts: -------------------------------------------------------------------------------- 1 | import { INotionEndpointsOptions } from '@nishans/endpoints'; 2 | import { ApolloServer } from 'apollo-server'; 3 | import { NotionGraphqlResolvers } from './Resolvers'; 4 | import { NotionGraphqlTypedefs } from './typedefs'; 5 | import { initializeNishan } from './utils'; 6 | 7 | export const server = async (options: Required) => { 8 | const context = await initializeNishan(options); 9 | 10 | return new ApolloServer({ 11 | typeDefs: NotionGraphqlTypedefs, 12 | resolvers: NotionGraphqlResolvers, 13 | context 14 | }); 15 | }; 16 | -------------------------------------------------------------------------------- /packages/graphql/libs/utils/index.ts: -------------------------------------------------------------------------------- 1 | export * from './initializeNishan'; 2 | -------------------------------------------------------------------------------- /packages/graphql/libs/utils/initializeNishan.ts: -------------------------------------------------------------------------------- 1 | import { NotionCore } from '@nishans/core'; 2 | import { INotionEndpointsOptions } from '@nishans/endpoints'; 3 | 4 | export async function initializeNishan ({ token, interval, user_id }: Required) { 5 | const nishan = new NotionCore.Api.Nishan({ 6 | token, 7 | interval 8 | }); 9 | 10 | const notion_user = await nishan.getNotionUser(user_id); 11 | 12 | const context = () => notion_user.getProps(); 13 | return context; 14 | } 15 | -------------------------------------------------------------------------------- /packages/graphql/tests/Resolvers/utils/getParentResolveType.test.ts: -------------------------------------------------------------------------------- 1 | import { getParentResolveType } from '../../../libs/Resolvers/utils'; 2 | 3 | describe('getParentResolveType', () => { 4 | it(`type = page`, () => { 5 | expect(getParentResolveType({ type: 'page' } as any)).toStrictEqual('Page'); 6 | }); 7 | it(`type = collection_view_page`, () => { 8 | expect(getParentResolveType({ type: 'collection_view_page' } as any)).toStrictEqual('CollectionViewPage'); 9 | }); 10 | it(`type = collection_view`, () => { 11 | expect(getParentResolveType({ type: 'collection_view' } as any)).toStrictEqual(undefined); 12 | }); 13 | it(`type = space`, () => { 14 | expect(getParentResolveType({ pages: [] } as any)).toStrictEqual('Space'); 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /packages/graphql/tests/server.test.ts: -------------------------------------------------------------------------------- 1 | import { NotionCore } from '@nishans/core'; 2 | import { ApolloServer } from 'apollo-server'; 3 | import { NotionGraphql } from '../libs'; 4 | 5 | afterEach(() => { 6 | jest.restoreAllMocks(); 7 | }); 8 | 9 | it('server', async () => { 10 | const getNotionUserMock = jest 11 | .spyOn(NotionCore.Api.Nishan.prototype, 'getNotionUser') 12 | .mockImplementationOnce(async () => undefined as any); 13 | 14 | const server = await NotionGraphql.server({ logger: false, interval: 0, token: 'token', user_id: 'user_root_1' }); 15 | 16 | expect(getNotionUserMock).toHaveBeenCalledWith('user_root_1'); 17 | expect(server instanceof ApolloServer).toBe(true); 18 | }); 19 | -------------------------------------------------------------------------------- /packages/graphql/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.shared.json", 3 | "include": [ 4 | "./libs/index.ts", 5 | "./experiment", 6 | "./examples" 7 | ], 8 | "compilerOptions": { 9 | "outDir": "./dist", 10 | "rootDir": "./", 11 | }, 12 | } -------------------------------------------------------------------------------- /packages/idz/libs/Generate/generateShortId.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Creates a notion collection schema compatible id 3 | * @param length The length of the short id 4 | */ 5 | export function generateShortId (length = 4) { 6 | let result = ''; 7 | const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; 8 | for (let i = 0; i < length; i++) result += characters.charAt(Math.floor(Math.random() * characters.length)); 9 | return result; 10 | } 11 | -------------------------------------------------------------------------------- /packages/idz/libs/Generate/index.ts: -------------------------------------------------------------------------------- 1 | import { generateId } from './generateId'; 2 | import { generateShortId } from './generateShortId'; 3 | 4 | export const NotionIdzGenerate = { 5 | shortId: generateShortId, 6 | id: generateId 7 | }; 8 | -------------------------------------------------------------------------------- /packages/idz/libs/Transform/index.ts: -------------------------------------------------------------------------------- 1 | import { transformToId } from './transformToId'; 2 | import { transformToUuid } from './transformToUuid'; 3 | 4 | export const NotionIdzTransform = { 5 | toId: transformToId, 6 | toUuid: transformToUuid 7 | }; 8 | -------------------------------------------------------------------------------- /packages/idz/libs/Transform/transformToId.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * convert notion uuid to id 3 | * @param uuid The uuid to convert to an id 4 | * @returns The converted id 5 | */ 6 | export const transformToId = (uuid: string) => uuid.replace(/-/g, ''); 7 | -------------------------------------------------------------------------------- /packages/idz/libs/Transform/transformToUuid.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Convert notion id to uuid 3 | * @param id The id to convert to uuid 4 | * @returns The converted notion uuid 5 | */ 6 | export const transformToUuid = (id: string) => 7 | `${id.substr(0, 8)}-${id.substr(8, 4)}-${id.substr(12, 4)}-${id.substr(16, 4)}-${id.substr(20)}`; 8 | -------------------------------------------------------------------------------- /packages/idz/libs/Validate/index.ts: -------------------------------------------------------------------------------- 1 | import { validateId } from './validateId'; 2 | import { validateUuid } from './validateUuid'; 3 | 4 | export const NotionIdzValidate = { 5 | uuid: validateUuid, 6 | id: validateId 7 | }; 8 | -------------------------------------------------------------------------------- /packages/idz/libs/Validate/validateId.ts: -------------------------------------------------------------------------------- 1 | import { NotionIdz } from '..'; 2 | 3 | export const validateId = (id: string) => NotionIdz.Validate.uuid(id); 4 | -------------------------------------------------------------------------------- /packages/idz/libs/Validate/validateUuid.ts: -------------------------------------------------------------------------------- 1 | import { NotionIdz } from '..'; 2 | 3 | export const validateUuid = (id: string) => 4 | Boolean( 5 | NotionIdz.Transform.toUuid(NotionIdz.Transform.toId(id)).match(/^[a-z0-9]{8}-(?:[a-z0-9]{4}-){3}[a-z0-9]{12}$/) 6 | ); 7 | -------------------------------------------------------------------------------- /packages/idz/libs/index.ts: -------------------------------------------------------------------------------- 1 | import { NotionIdzGenerate } from './Generate'; 2 | import { NotionIdzTransform } from './Transform'; 3 | import { NotionIdzValidate } from './Validate'; 4 | 5 | export const NotionIdz = { 6 | Generate: NotionIdzGenerate, 7 | Transform: NotionIdzTransform, 8 | Validate: NotionIdzValidate 9 | }; 10 | -------------------------------------------------------------------------------- /packages/idz/tests/Generate/generateShortId.test.ts: -------------------------------------------------------------------------------- 1 | import { NotionIdz } from '../../libs'; 2 | 3 | it(`Should create short id with default length`, () => { 4 | const short_id = NotionIdz.Generate.shortId(); 5 | expect(short_id).toBeTruthy(); 6 | expect(short_id.length).toBe(4); 7 | }); 8 | 9 | it(`Should create short id with custom length`, () => { 10 | const short_id = NotionIdz.Generate.shortId(6); 11 | expect(short_id).toBeTruthy(); 12 | expect(short_id.length).toBe(6); 13 | }); 14 | -------------------------------------------------------------------------------- /packages/idz/tests/Transform/toId.test.ts: -------------------------------------------------------------------------------- 1 | import { NotionIdz } from '../../libs'; 2 | 3 | it('Should output correctly for uuidToId function', () => { 4 | expect(NotionIdz.Transform.toId('dd721d8b-bf35-4036-bdcd-e9378e8b7e83')).toBe('dd721d8bbf354036bdcde9378e8b7e83'); 5 | }); 6 | -------------------------------------------------------------------------------- /packages/idz/tests/Transform/toUuid.test.ts: -------------------------------------------------------------------------------- 1 | import { NotionIdz } from '../../libs'; 2 | 3 | it('Should output correctly for idToUuid function', () => { 4 | expect(NotionIdz.Transform.toUuid('dd721d8bbf354036bdcde9378e8b7e83')).toBe('dd721d8b-bf35-4036-bdcd-e9378e8b7e83'); 5 | }); 6 | -------------------------------------------------------------------------------- /packages/idz/tests/Validate/validateId.test.ts: -------------------------------------------------------------------------------- 1 | import { NotionIdz } from '../../libs'; 2 | 3 | describe('NotionIdz.validateId', () => { 4 | it(`return true`, () => { 5 | expect(NotionIdz.Validate.id('d25d58cf0ebc436daecba1987fd9afab')).toBe(true); 6 | }); 7 | 8 | it(`return false`, () => { 9 | expect(NotionIdz.Validate.id('d25d58cf0ebc436daecba1987fd9afa')).toBe(false); 10 | }); 11 | }); 12 | -------------------------------------------------------------------------------- /packages/idz/tests/Validate/validateUuid.test.ts: -------------------------------------------------------------------------------- 1 | import { NotionIdz } from '../../libs'; 2 | 3 | describe('NotionIdz.validateUuid', () => { 4 | it(`return true`, () => { 5 | expect(NotionIdz.Validate.uuid('d25d58cf-0ebc-436d-aecb-a1987fd9afab')).toBe(true); 6 | }); 7 | 8 | it(`return false`, () => { 9 | expect(NotionIdz.Validate.uuid('d25d58cf-0ebc-436d-aecb-a1987fd9afa')).toBe(false); 10 | }); 11 | }); 12 | -------------------------------------------------------------------------------- /packages/idz/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.shared.json", 3 | "include": [ 4 | "./libs/index.ts", 5 | "./experiment" 6 | ], 7 | "compilerOptions": { 8 | "outDir": "./dist", 9 | "rootDir": "./" 10 | } 11 | } -------------------------------------------------------------------------------- /packages/init/libs/View/filter.ts: -------------------------------------------------------------------------------- 1 | import { IViewFilter, TView } from '@nishans/types'; 2 | 3 | /** 4 | * Adds filter specific data to the view 5 | * @param data The view to initialize filter data to 6 | */ 7 | export function initializeViewFilters (data: TView) { 8 | // If query2 doesn't exist, assign it to a default one with default filter 9 | if (!data.query2) data.query2 = { filter: { operator: 'and', filters: [] } } as any; 10 | // If query2.filter doesn't exist, assign it to a default one 11 | if (data.query2 && !data.query2.filter) data.query2.filter = { operator: 'and', filters: [] }; 12 | // Return the filter object 13 | return (data.query2 as any).filter as IViewFilter; 14 | } 15 | -------------------------------------------------------------------------------- /packages/init/libs/View/index.ts: -------------------------------------------------------------------------------- 1 | import { initializeViewAggregations } from './aggregation'; 2 | import { initializeViewFilters } from './filter'; 3 | import { initializeViewSorts } from './sort'; 4 | 5 | export const NotionInitView = { 6 | sort: initializeViewSorts, 7 | aggregation: initializeViewAggregations, 8 | filter: initializeViewFilters 9 | }; 10 | -------------------------------------------------------------------------------- /packages/init/libs/View/sort.ts: -------------------------------------------------------------------------------- 1 | import { TView, ViewSorts } from '@nishans/types'; 2 | 3 | /** 4 | * Adds sort specific data to the view 5 | * @param data The view to initialize sort data to 6 | */ 7 | export function initializeViewSorts (data: TView) { 8 | // If query2 doesn't exist, assign it to a default one with default sort 9 | if (!data.query2) data.query2 = { sort: [] } as any; 10 | // If query2.sort doesn't exist, assign it to a default one 11 | if (data.query2 && !data.query2.sort) data.query2.sort = []; 12 | // Return the sort array 13 | return (data.query2 as any).sort as ViewSorts[]; 14 | } 15 | -------------------------------------------------------------------------------- /packages/init/libs/blockMetadata.ts: -------------------------------------------------------------------------------- 1 | import { TBlock } from '@nishans/types'; 2 | 3 | export const blockMetadata = ( 4 | arg: Pick 5 | ) => { 6 | return { 7 | created_time: Date.now(), 8 | created_by_id: arg.created_by_id, 9 | created_by_table: 'notion_user', 10 | last_edited_time: Date.now(), 11 | last_edited_by_table: 'notion_user', 12 | last_edited_by_id: arg.last_edited_by_id, 13 | space_id: arg.space_id, 14 | version: 0, 15 | alive: true 16 | }; 17 | }; 18 | -------------------------------------------------------------------------------- /packages/init/libs/collection.ts: -------------------------------------------------------------------------------- 1 | import { ICollection } from '@nishans/types'; 2 | 3 | export const collection = ( 4 | arg: Pick 5 | ) => { 6 | return { 7 | id: arg.id, 8 | schema: arg.schema, 9 | cover: arg.cover, 10 | icon: arg.icon, 11 | parent_id: arg.parent_id, 12 | parent_table: 'block', 13 | alive: true, 14 | name: arg.name, 15 | migrated: false, 16 | version: 0, 17 | format: arg.format 18 | } as ICollection; 19 | }; 20 | -------------------------------------------------------------------------------- /packages/init/libs/comment.ts: -------------------------------------------------------------------------------- 1 | import { IComment } from '@nishans/types'; 2 | 3 | export const comment = ( 4 | arg: Pick< 5 | IComment, 6 | 'parent_id' | 'text' | 'id' | 'space_id' | 'created_by_id' 7 | > 8 | ) => { 9 | return { 10 | parent_id: arg.parent_id, 11 | parent_table: 'discussion', 12 | text: arg.text, 13 | alive: true, 14 | id: arg.id, 15 | version: 1, 16 | space_id: arg.space_id, 17 | created_by_id: arg.created_by_id, 18 | created_by_table: 'notion_user', 19 | created_time: Date.now(), 20 | last_edited_by_table: 'notion_user', 21 | last_edited_time: Date.now() 22 | } as IComment; 23 | }; 24 | -------------------------------------------------------------------------------- /packages/init/libs/discussion.ts: -------------------------------------------------------------------------------- 1 | import { IDiscussion } from '@nishans/types'; 2 | 3 | export const discussion = ( 4 | arg: Pick< 5 | IDiscussion, 6 | 'resolved' | 'context' | 'comments' | 'parent_id' | 'id' | 'space_id' 7 | > 8 | ) => { 9 | return { 10 | parent_id: arg.parent_id, 11 | parent_table: 'block', 12 | context: arg.context, 13 | id: arg.id, 14 | version: 1, 15 | space_id: arg.space_id, 16 | comments: arg.comments, 17 | resolved: arg.resolved 18 | } as IDiscussion; 19 | }; 20 | -------------------------------------------------------------------------------- /packages/init/libs/index.ts: -------------------------------------------------------------------------------- 1 | import { blockMetadata } from './blockMetadata'; 2 | import { collection } from './collection'; 3 | import { comment } from './comment'; 4 | import { discussion } from './discussion'; 5 | import { spaceView } from './spaceView'; 6 | import { NotionInitView } from './View'; 7 | 8 | export const NotionInit = { 9 | View: NotionInitView, 10 | blockMetadata, 11 | comment, 12 | discussion, 13 | spaceView, 14 | collection 15 | }; 16 | -------------------------------------------------------------------------------- /packages/init/libs/spaceView.ts: -------------------------------------------------------------------------------- 1 | import { ISpaceView } from '@nishans/types'; 2 | 3 | export const spaceView = (arg: Pick) => { 4 | return { 5 | created_getting_started: false, 6 | created_onboarding_templates: false, 7 | space_id: arg.space_id, 8 | notify_mobile: true, 9 | notify_desktop: true, 10 | notify_email: true, 11 | parent_id: arg.parent_id, 12 | parent_table: 'user_root', 13 | alive: true, 14 | joined: true, 15 | id: arg.id, 16 | version: 1, 17 | visited_templates: [], 18 | sidebar_hidden_templates: [], 19 | bookmarked_pages: [] 20 | } as ISpaceView; 21 | }; 22 | -------------------------------------------------------------------------------- /packages/init/tests/View/aggregation.test.ts: -------------------------------------------------------------------------------- 1 | import { NotionInit } from '../../libs'; 2 | 3 | it(`Should create query2 and return aggregations`, () => { 4 | const view: any = {}; 5 | const aggregations = NotionInit.View.aggregation(view); 6 | expect(aggregations).toStrictEqual([]); 7 | expect(view).toStrictEqual({ 8 | query2: { 9 | aggregations: [] 10 | } 11 | }); 12 | }); 13 | 14 | it(`Should create and return aggregations`, () => { 15 | const view: any = { query2: { sort: [] } }; 16 | const aggregations = NotionInit.View.aggregation(view); 17 | expect(aggregations).toStrictEqual([]); 18 | expect(view).toStrictEqual({ 19 | query2: { 20 | sort: [], 21 | aggregations: [] 22 | } 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /packages/init/tests/View/sort.test.ts: -------------------------------------------------------------------------------- 1 | import { NotionInit } from '../../libs'; 2 | 3 | it(`Should create query2 and return sort`, () => { 4 | const view: any = {}; 5 | const sort = NotionInit.View.sort(view); 6 | expect(sort).toStrictEqual([]); 7 | expect(view).toStrictEqual({ 8 | query2: { 9 | sort: [] 10 | } 11 | }); 12 | }); 13 | 14 | it(`Should create and return sort`, () => { 15 | const view: any = { query2: { aggregations: [] } }; 16 | const sort = NotionInit.View.sort(view); 17 | expect(sort).toStrictEqual([]); 18 | expect(view).toStrictEqual({ 19 | query2: { 20 | sort: [], 21 | aggregations: [] 22 | } 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /packages/init/tests/blockMetadata.test.ts: -------------------------------------------------------------------------------- 1 | import { NotionInit } from '../libs'; 2 | 3 | it(`blockMetadata`, () => { 4 | expect( 5 | NotionInit.blockMetadata({ 6 | created_by_id: 'user_1', 7 | last_edited_by_id: 'user_1', 8 | 9 | space_id: 'space_1' 10 | }) 11 | ).toStrictEqual( 12 | expect.objectContaining({ 13 | created_by_id: 'user_1', 14 | last_edited_by_id: 'user_1', 15 | 16 | space_id: 'space_1', 17 | version: 0, 18 | alive: true, 19 | created_time: expect.any(Number), 20 | last_edited_time: expect.any(Number), 21 | last_edited_by_table: 'notion_user', 22 | created_by_table: 'notion_user' 23 | }) 24 | ); 25 | }); 26 | -------------------------------------------------------------------------------- /packages/init/tests/collection.test.ts: -------------------------------------------------------------------------------- 1 | import { NotionInit } from '../libs'; 2 | 3 | it(`collection`, () => { 4 | const arg: any = { 5 | id: 'collection_1', 6 | schema: {}, 7 | cover: '', 8 | icon: '', 9 | parent_id: 'block_1', 10 | format: {}, 11 | name: [ [ 'Collection' ] ] 12 | }; 13 | expect(NotionInit.collection(arg)).toStrictEqual( 14 | expect.objectContaining({ 15 | ...arg, 16 | parent_table: 'block', 17 | alive: true, 18 | migrated: false, 19 | version: 0 20 | }) 21 | ); 22 | }); 23 | -------------------------------------------------------------------------------- /packages/init/tests/comment.test.ts: -------------------------------------------------------------------------------- 1 | import { NotionInit } from '../libs'; 2 | 3 | it(`comment`, () => { 4 | const arg: any = { 5 | created_by_id: 'notion_user_1', 6 | id: 'comment_1', 7 | parent_id: 'discussion_1', 8 | space_id: 'space_1', 9 | text: [['Text']] 10 | }; 11 | expect(NotionInit.comment(arg)).toStrictEqual( 12 | expect.objectContaining({ 13 | ...arg, 14 | parent_table: 'discussion', 15 | alive: true, 16 | version: 1, 17 | created_by_table: 'notion_user', 18 | created_time: expect.any(Number), 19 | last_edited_time: expect.any(Number) 20 | }) 21 | ); 22 | }); 23 | -------------------------------------------------------------------------------- /packages/init/tests/discussion.test.ts: -------------------------------------------------------------------------------- 1 | import { NotionInit } from '../libs'; 2 | 3 | it(`discussion`, () => { 4 | const arg: any = { 5 | comments: ['comment_1'], 6 | resolved: false, 7 | id: 'comment_1', 8 | parent_id: 'discussion_1', 9 | 10 | space_id: 'space_1', 11 | context: [['Text']] 12 | }; 13 | expect(NotionInit.discussion(arg)).toStrictEqual( 14 | expect.objectContaining({ 15 | ...arg, 16 | parent_table: 'block', 17 | version: 1 18 | }) 19 | ); 20 | }); 21 | -------------------------------------------------------------------------------- /packages/init/tests/spaceView.test.ts: -------------------------------------------------------------------------------- 1 | import { NotionInit } from '../libs'; 2 | 3 | it(`spaceView`, () => { 4 | const arg: any = { 5 | id: 'space_view_1', 6 | parent_id: 'user_root_1', 7 | space_id: 'space_1' 8 | }; 9 | 10 | expect(NotionInit.spaceView(arg)).toStrictEqual({ 11 | ...arg, 12 | created_getting_started: false, 13 | created_onboarding_templates: false, 14 | notify_mobile: true, 15 | notify_desktop: true, 16 | notify_email: true, 17 | parent_table: 'user_root', 18 | alive: true, 19 | joined: true, 20 | version: 1, 21 | visited_templates: [], 22 | sidebar_hidden_templates: [], 23 | bookmarked_pages: [] 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /packages/init/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.shared.json", 3 | "include": [ 4 | "./libs/index.ts", 5 | "./experiment", 6 | "./examples" 7 | ], 8 | "compilerOptions": { 9 | "outDir": "./dist", 10 | "rootDir": "./", 11 | }, 12 | } -------------------------------------------------------------------------------- /packages/inline-blocks/libs/index.ts: -------------------------------------------------------------------------------- 1 | export * from './NotionInlineBlock'; 2 | export * from './TextHighlightColor'; 3 | export * from './TextStyleFormatter'; 4 | -------------------------------------------------------------------------------- /packages/inline-blocks/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.shared.json", 3 | "include": [ 4 | "./src/index.ts", 5 | "./libs/index.ts", 6 | "./experiment", 7 | "./examples" 8 | ], 9 | "compilerOptions": { 10 | "outDir": "./dist", 11 | "rootDir": "./" 12 | } 13 | } -------------------------------------------------------------------------------- /packages/lineage/libs/Block/getCommentIds.ts: -------------------------------------------------------------------------------- 1 | import { INotionCache, IText, TBlock } from '@nishans/types'; 2 | 3 | export const getCommentIds = (block: TBlock, cache: INotionCache) => { 4 | const comment_ids: string[] = []; 5 | (block as IText).discussions?.forEach(discussion_id=>{ 6 | const discussion_data = cache.discussion.get(discussion_id); 7 | if(discussion_data) 8 | comment_ids.push(...discussion_data.comments); 9 | }) 10 | 11 | return comment_ids; 12 | }; 13 | -------------------------------------------------------------------------------- /packages/lineage/libs/Block/index.ts: -------------------------------------------------------------------------------- 1 | import { getCommentIds } from './getCommentIds'; 2 | 3 | export const NotionLineageBlock = { 4 | getCommentIds 5 | }; 6 | -------------------------------------------------------------------------------- /packages/lineage/libs/Collection/getRowPageIds.ts: -------------------------------------------------------------------------------- 1 | import { INotionCacheOptions, NotionCache } from '@nishans/cache'; 2 | 3 | export async function getRowPageIds (id: string, props: INotionCacheOptions) { 4 | await NotionCache.initializeCacheForSpecificData(id, 'collection', props); 5 | const page_ids: string[] = []; 6 | for (const [ , page ] of props.cache.block) 7 | if ( 8 | page && 9 | page.type === 'page' && 10 | page.parent_table === 'collection' && 11 | page.parent_id === id && 12 | !page.is_template 13 | ) 14 | page_ids.push(page.id); 15 | return page_ids; 16 | } 17 | -------------------------------------------------------------------------------- /packages/lineage/libs/Collection/index.ts: -------------------------------------------------------------------------------- 1 | import { getRowPageIds } from './getRowPageIds'; 2 | 3 | export const NotionLineageCollection = { 4 | getRowPageIds 5 | }; 6 | -------------------------------------------------------------------------------- /packages/lineage/libs/NotionUser/getSpaceIds.ts: -------------------------------------------------------------------------------- 1 | import { INotionCache } from '@nishans/types'; 2 | 3 | export function getSpaceIds (cache: INotionCache) { 4 | const space_ids: string[] = []; 5 | for (const [ space_id ] of cache.space) space_ids.push(space_id); 6 | return space_ids; 7 | } 8 | -------------------------------------------------------------------------------- /packages/lineage/libs/NotionUser/index.ts: -------------------------------------------------------------------------------- 1 | import { getSpaceIds } from './getSpaceIds'; 2 | 3 | export const NotionLineageNotionUser = { 4 | getSpaceIds 5 | }; 6 | -------------------------------------------------------------------------------- /packages/lineage/libs/Page/getCommentIds.ts: -------------------------------------------------------------------------------- 1 | import { INotionCache, IPage } from '@nishans/types'; 2 | import { NotionLineage } from '../'; 3 | 4 | export const getCommentIds = (page: IPage, cache: INotionCache) => { 5 | const comment_ids: string[] = []; 6 | 7 | page.content.forEach((block_id) => { 8 | const block_data = cache.block.get(block_id); 9 | if (block_data) comment_ids.push(...NotionLineage.Block.getCommentIds(block_data, cache)); 10 | }); 11 | 12 | return comment_ids; 13 | }; 14 | -------------------------------------------------------------------------------- /packages/lineage/libs/Page/getDiscussionIds.ts: -------------------------------------------------------------------------------- 1 | import { INotionCache, IPage } from '@nishans/types'; 2 | 3 | export const getDiscussionIds = (page: IPage, cache: INotionCache) => { 4 | const discussion_ids: string[] = [...(page.discussions ?? [])]; 5 | 6 | page.content.forEach((block_id) => { 7 | const block_data = cache.block.get(block_id); 8 | if ((block_data as any)?.discussions) discussion_ids.push(...(block_data as any).discussions); 9 | }); 10 | 11 | return discussion_ids; 12 | }; 13 | -------------------------------------------------------------------------------- /packages/lineage/libs/Page/getFollowId.ts: -------------------------------------------------------------------------------- 1 | import { INotionCache } from '@nishans/types'; 2 | 3 | export const getFollowId = (id: string, cache: INotionCache) => { 4 | for (const [ , follow ] of cache.follow) { 5 | if (follow.navigable_block_id === id) return follow.id; 6 | } 7 | }; 8 | -------------------------------------------------------------------------------- /packages/lineage/libs/Page/index.ts: -------------------------------------------------------------------------------- 1 | import { getCommentIds } from './getCommentIds'; 2 | import { getDiscussionIds } from './getDiscussionIds'; 3 | import { getFollowId } from './getFollowId'; 4 | 5 | export const NotionLineagePage = { 6 | getDiscussionIds, 7 | getCommentIds, 8 | getFollowId 9 | }; 10 | -------------------------------------------------------------------------------- /packages/lineage/libs/Space/getSpaceView.ts: -------------------------------------------------------------------------------- 1 | import { INotionCache, ISpaceView } from '@nishans/types'; 2 | 3 | export function getSpaceView (space_id: string, cache: INotionCache) { 4 | let target_space_view: ISpaceView | null = null; 5 | for (const [ , space_view ] of cache.space_view) { 6 | if (space_view.space_id === space_id) { 7 | target_space_view = space_view; 8 | break; 9 | } 10 | } 11 | return target_space_view; 12 | } 13 | -------------------------------------------------------------------------------- /packages/lineage/libs/Space/index.ts: -------------------------------------------------------------------------------- 1 | import { getSpaceView } from './getSpaceView'; 2 | 3 | export const NotionLineageSpace = { 4 | getSpaceView 5 | }; 6 | -------------------------------------------------------------------------------- /packages/lineage/libs/getPageIds.ts: -------------------------------------------------------------------------------- 1 | import { INotionCache, TBlock } from '@nishans/types'; 2 | 3 | export const getPageIds = (cache: INotionCache) => { 4 | return Array.from(cache.block.keys()).filter((id) => 5 | (cache.block.get(id) as TBlock).type.match(/^(page|collection_view_page)$/) 6 | ); 7 | }; 8 | -------------------------------------------------------------------------------- /packages/lineage/libs/types.ts: -------------------------------------------------------------------------------- 1 | export type INotionRepositionParams = 2 | | { 3 | id: string; 4 | position: 'Before' | 'After'; 5 | } 6 | | number 7 | | undefined; 8 | -------------------------------------------------------------------------------- /packages/lineage/tests/NotionUser/getSpaceIds.test.ts: -------------------------------------------------------------------------------- 1 | import { NotionCache } from '@nishans/cache'; 2 | import { NotionLineage } from '../../libs'; 3 | 4 | it(`getSpaceIds`, () => { 5 | const cache = { 6 | ...NotionCache.createDefaultCache(), 7 | space: new Map([ [ 'space_1', {} ], [ 'space_2', {} ] ]) 8 | } as any; 9 | 10 | const space_ids = NotionLineage.NotionUser.getSpaceIds(cache); 11 | 12 | expect(space_ids).toStrictEqual([ 'space_1', 'space_2' ]); 13 | }); 14 | -------------------------------------------------------------------------------- /packages/lineage/tests/Page/getFollowId.test.ts: -------------------------------------------------------------------------------- 1 | import { NotionCache } from '@nishans/cache'; 2 | import { NotionLineage } from '../../libs'; 3 | 4 | it(`getFollowId`, () => { 5 | const follow_1: any = { navigable_block_id: 'block_2', id: 'follow_2' }, 6 | follow_2: any = { navigable_block_id: 'block_1', id: 'follow_1' }, 7 | cache = { 8 | ...NotionCache.createDefaultCache(), 9 | follow: new Map([ [ 'follow_1', follow_1 ], [ 'follow_2', follow_2 ] ]) 10 | }; 11 | 12 | const follow_id = NotionLineage.Page.getFollowId('block_1', cache); 13 | expect(follow_id).toStrictEqual('follow_1'); 14 | }); 15 | -------------------------------------------------------------------------------- /packages/lineage/tests/getPageIds.test.ts: -------------------------------------------------------------------------------- 1 | import { NotionCache } from '@nishans/cache'; 2 | import { NotionLineage } from '../libs'; 3 | 4 | it(`NotionLineage.getPageIds`, () => { 5 | expect( 6 | NotionLineage.getPageIds({ 7 | ...NotionCache.createDefaultCache(), 8 | block: new Map([ 9 | [ 'block_1', { type: 'collection_view_page' } as any ], 10 | [ 'block_2', { type: 'page' } as any ], 11 | [ 'block_3', { type: 'header' } as any ] 12 | ]) 13 | }) 14 | ); 15 | }); 16 | -------------------------------------------------------------------------------- /packages/lineage/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.shared.json", 3 | "include": [ 4 | "./libs/index.ts", 5 | "./experiment", 6 | "./examples" 7 | ], 8 | "compilerOptions": { 9 | "outDir": "./dist", 10 | "rootDir": "./", 11 | }, 12 | } -------------------------------------------------------------------------------- /packages/logger/libs/endpointLogger.ts: -------------------------------------------------------------------------------- 1 | import colors from 'colors'; 2 | import { createLogger, format, transports } from 'winston'; 3 | 4 | const { combine, colorize, timestamp, printf } = format; 5 | 6 | export const endpointLogger = createLogger({ 7 | level: 'info', 8 | format: combine( 9 | colorize(), 10 | timestamp({ 11 | format: 'HH:mm:ss' 12 | }), 13 | printf( 14 | ({ level, message, timestamp }) => `${colors.blue.bold(timestamp)} - ${level}: ${colors.bold.white(message)}` 15 | ) 16 | ), 17 | transports: [ new transports.Console() ] 18 | }); 19 | -------------------------------------------------------------------------------- /packages/logger/libs/errorLogger.ts: -------------------------------------------------------------------------------- 1 | import colors from 'colors'; 2 | 3 | export const errorLogger = (msg: string) => { 4 | throw new Error(colors.red.bold(msg)); 5 | }; 6 | -------------------------------------------------------------------------------- /packages/logger/libs/index.ts: -------------------------------------------------------------------------------- 1 | import { endpointLogger } from './endpointLogger'; 2 | import { errorLogger } from './errorLogger'; 3 | import { methodLogger } from './methodLogger'; 4 | 5 | export const NotionLogger = { 6 | endpoint: endpointLogger, 7 | method: methodLogger, 8 | error: errorLogger 9 | }; 10 | -------------------------------------------------------------------------------- /packages/logger/libs/methodLogger.ts: -------------------------------------------------------------------------------- 1 | import colors from 'colors'; 2 | import { createLogger, format, transports } from 'winston'; 3 | 4 | const { combine, colorize, timestamp, printf } = format; 5 | 6 | export const methodLogger = createLogger({ 7 | level: 'info', 8 | format: combine( 9 | colorize(), 10 | timestamp({ 11 | format: 'HH:mm:ss' 12 | }), 13 | printf( 14 | ({ level, message, timestamp }) => `${colors.blue.bold(timestamp)} - ${level}: ${colors.bold.white(message)}` 15 | ) 16 | ), 17 | transports: [ new transports.Console() ] 18 | }); 19 | -------------------------------------------------------------------------------- /packages/logger/tests/endpointLogger.test.ts: -------------------------------------------------------------------------------- 1 | import { NotionLogger } from '../libs'; 2 | 3 | afterEach(() => { 4 | jest.restoreAllMocks(); 5 | }); 6 | 7 | it(`NotionLogger.endpointLogger`, () => { 8 | const stdoutWriteMock = jest.spyOn((console as any)._stdout, 'write'); 9 | NotionLogger.endpoint.warn(`warning`); 10 | expect((stdoutWriteMock.mock.calls[0][0] as string).includes('warning')).toBe(true); 11 | }); 12 | -------------------------------------------------------------------------------- /packages/logger/tests/errorLogger.test.ts: -------------------------------------------------------------------------------- 1 | import colors from 'colors'; 2 | import { NotionLogger } from '../libs'; 3 | 4 | afterEach(() => { 5 | jest.restoreAllMocks(); 6 | }); 7 | 8 | it(`NotionLogger.methodLogger`, () => { 9 | expect(() => NotionLogger.error(`error`)).toThrow(colors.red.bold(`error`)); 10 | }); 11 | -------------------------------------------------------------------------------- /packages/logger/tests/methodLogger.test.ts: -------------------------------------------------------------------------------- 1 | import { NotionLogger } from '../libs'; 2 | 3 | afterEach(() => { 4 | jest.restoreAllMocks(); 5 | }); 6 | 7 | it(`NotionLogger.methodLogger`, () => { 8 | const stdoutWriteMock = jest.spyOn((console as any)._stdout, 'write'); 9 | NotionLogger.method.warn(`warning`); 10 | expect((stdoutWriteMock.mock.calls[0][0] as string).includes('warning')).toBe(true); 11 | }); 12 | -------------------------------------------------------------------------------- /packages/logger/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.shared.json", 3 | "include": [ 4 | "./libs/index.ts", 5 | "./experiment", 6 | "./examples" 7 | ], 8 | "compilerOptions": { 9 | "outDir": "./dist", 10 | "rootDir": "./", 11 | }, 12 | } -------------------------------------------------------------------------------- /packages/markdown/examples/example.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Hello World 3 | --- 4 | 5 | :: "Regular Text" [bg=red,f=b]"Red Bold background" :: 6 | 7 | *Italic* **Bold** `code` -------------------------------------------------------------------------------- /packages/markdown/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './uploadMarkdown'; 2 | export * from '../utils'; 3 | export * from './types'; 4 | -------------------------------------------------------------------------------- /packages/markdown/utils/convertFrontMatter2Obj.ts: -------------------------------------------------------------------------------- 1 | export function convertFrontMatter2Obj (frontmatter: string) { 2 | const lines = frontmatter.split('\n'); 3 | const obj: Record = {}; 4 | lines.forEach((line) => { 5 | const match = line.match(/(?:(\w+):\s(.+))/); 6 | if (match) { 7 | const [ , key, value ] = match; 8 | obj[key] = value; 9 | } 10 | }); 11 | return obj; 12 | } 13 | -------------------------------------------------------------------------------- /packages/markdown/utils/createTransactions.ts: -------------------------------------------------------------------------------- 1 | import { IOperation, SaveTransactionParams } from '@nishans/types'; 2 | 3 | import { v4 as uuidv4 } from 'uuid'; 4 | 5 | export function createTransaction (shardId: number, spaceId: string, operations: IOperation[]) { 6 | return { 7 | requestId: uuidv4(), 8 | transactions: [ 9 | { 10 | id: uuidv4(), 11 | shardId, 12 | spaceId, 13 | operations 14 | } 15 | ] 16 | } as SaveTransactionParams; 17 | } 18 | -------------------------------------------------------------------------------- /packages/markdown/utils/index.ts: -------------------------------------------------------------------------------- 1 | export * from './parseFile'; 2 | export * from './mdast2NotionBlocks'; 3 | export * from './convertFrontMatter2Obj'; 4 | export * from './getNotionData'; 5 | export * from './createTransactions'; 6 | export * from './notionBlocks2Operations'; 7 | export * from './uploadToNotion'; 8 | export * from './parseParagraphNode'; 9 | export * from './parseListNode'; 10 | export * from './parseNodes'; 11 | -------------------------------------------------------------------------------- /packages/markdown/utils/parseFile.ts: -------------------------------------------------------------------------------- 1 | import notion from '@nishans/remark-notion'; 2 | import fs from 'fs'; 3 | import frontmatter from 'remark-frontmatter'; 4 | import markdown from 'remark-parse'; 5 | import unified from 'unified'; 6 | 7 | const processor = unified().use(markdown).use(frontmatter, [ 'yaml' ]).use(notion); 8 | 9 | export async function parseFile (path: string) { 10 | return parseContent(await fs.promises.readFile(path, 'utf-8')); 11 | } 12 | 13 | export function parseContent (content: string) { 14 | return processor.parse(content); 15 | } 16 | -------------------------------------------------------------------------------- /packages/markdown/utils/uploadToNotion.ts: -------------------------------------------------------------------------------- 1 | import { IOperation } from '@nishans/types'; 2 | import axios from 'axios'; 3 | import { NotionOperationData } from '../src'; 4 | import { createTransaction } from './createTransactions'; 5 | 6 | export async function uploadToNotion( 7 | { space_id, headers }: NotionOperationData, 8 | notion_block_ops: IOperation[] 9 | ) { 10 | await axios.post( 11 | 'https://www.notion.so/api/v3/saveTransactions', 12 | createTransaction(space_id, notion_block_ops), 13 | headers 14 | ); 15 | } 16 | -------------------------------------------------------------------------------- /packages/notion-formula/libs/FunctionFormulaInfo/index.ts: -------------------------------------------------------------------------------- 1 | import { generateNotionFunctionFormulaInfoArray } from './array'; 2 | import { generateNotionFunctionFormulaInfoMap } from './map'; 3 | 4 | export const FunctionFormulaInfo = { 5 | array: generateNotionFunctionFormulaInfoArray, 6 | map: generateNotionFunctionFormulaInfoMap 7 | }; 8 | -------------------------------------------------------------------------------- /packages/notion-formula/libs/FunctionFormulaInfo/map.ts: -------------------------------------------------------------------------------- 1 | import { TFunctionName } from '@nishans/types'; 2 | import { FunctionFormulaInfo } from './'; 3 | import { IFunctionFormulaInfo } from './types'; 4 | 5 | export const generateNotionFunctionFormulaInfoMap = (): Map => 6 | new Map( 7 | FunctionFormulaInfo.array().map((function_formula_info) => [ 8 | function_formula_info.function_name, 9 | function_formula_info 10 | ]) 11 | ); 12 | -------------------------------------------------------------------------------- /packages/notion-formula/libs/FunctionFormulaInfo/types.ts: -------------------------------------------------------------------------------- 1 | import { TFormulaResultType, TFunctionName, TOperator } from '@nishans/types'; 2 | 3 | export type IFunctionFormulaSignature = { 4 | arity?: TFormulaResultType[]; 5 | result_type: TFormulaResultType; 6 | variadic?: TFormulaResultType; 7 | }; 8 | 9 | export interface IFunctionFormulaInfo { 10 | signatures: IFunctionFormulaSignature[]; 11 | function_name: TFunctionName; 12 | description: string; 13 | operator?: TOperator; 14 | } 15 | -------------------------------------------------------------------------------- /packages/notion-formula/libs/FunctionFormulaInfo/utils/generateFormulaInfo.ts: -------------------------------------------------------------------------------- 1 | import { TFormulaResultType, TFunctionName, TOperator } from '@nishans/types'; 2 | import { IFunctionFormulaInfo } from '../types'; 3 | 4 | export function generateFormulaInfo ( 5 | description: string, 6 | function_name: TFunctionName, 7 | signatures: [TFormulaResultType, TFormulaResultType[]][], 8 | operator?: TOperator 9 | ): IFunctionFormulaInfo { 10 | return { 11 | description, 12 | operator, 13 | function_name, 14 | signatures: signatures.map(([ result_type, arity ]) => ({ arity, result_type })) 15 | }; 16 | } 17 | -------------------------------------------------------------------------------- /packages/notion-formula/libs/FunctionFormulaInfo/utils/index.ts: -------------------------------------------------------------------------------- 1 | export * from './generateFormulaInfo'; 2 | -------------------------------------------------------------------------------- /packages/notion-formula/libs/GenerateAST/index.ts: -------------------------------------------------------------------------------- 1 | import { generateFormulaASTFromArray } from './array'; 2 | import { generateFormulaASTFromObject } from './object'; 3 | import { generateFormulaASTFromString } from './string'; 4 | 5 | export const GenerateAST = { 6 | string: generateFormulaASTFromString, 7 | object: generateFormulaASTFromObject, 8 | array: generateFormulaASTFromArray 9 | }; 10 | -------------------------------------------------------------------------------- /packages/notion-formula/libs/GenerateAST/utils/index.ts: -------------------------------------------------------------------------------- 1 | export * from './generateNotionFormulaAST'; 2 | export * from './getResultTypeFromSchemaType'; 3 | -------------------------------------------------------------------------------- /packages/notion-formula/libs/GenerateArg/index.ts: -------------------------------------------------------------------------------- 1 | import { generateNotionFormulaArgFromLiteral } from './literal'; 2 | import { generateNotionFormulaArgFromProperty } from './property'; 3 | 4 | export const GenerateArg = { 5 | literal: generateNotionFormulaArgFromLiteral, 6 | property: generateNotionFormulaArgFromProperty 7 | }; 8 | -------------------------------------------------------------------------------- /packages/notion-formula/libs/index.ts: -------------------------------------------------------------------------------- 1 | export * from '../types'; 2 | import { FunctionFormulaInfo } from './FunctionFormulaInfo'; 3 | import { GenerateArg } from './GenerateArg'; 4 | import { GenerateAST } from './GenerateAST'; 5 | import { generateSchemaMapFromRemoteSchema } from './generateSchemaMapFromRemoteSchema'; 6 | 7 | export const NotionFormula = { 8 | generateSchemaMapFromRemoteSchema, 9 | GenerateAST, 10 | GenerateArg, 11 | FunctionFormulaInfo 12 | }; 13 | -------------------------------------------------------------------------------- /packages/notion-formula/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.shared.json", 3 | "include": [ 4 | "./libs/index.ts", 5 | "./experiment", 6 | "examples" 7 | ], 8 | "compilerOptions": { 9 | "outDir": "./dist", 10 | "rootDir": "./" 11 | } 12 | } -------------------------------------------------------------------------------- /packages/notion-formula/types/index.ts: -------------------------------------------------------------------------------- 1 | export * from './formula-array'; 2 | export * from './formula-object'; 3 | -------------------------------------------------------------------------------- /packages/operations/libs/Plugins/Options/index.ts: -------------------------------------------------------------------------------- 1 | import { skipOption } from './skip'; 2 | 3 | export const NotionOperationsPluginOptions = { 4 | skip: skipOption 5 | }; 6 | -------------------------------------------------------------------------------- /packages/operations/libs/Plugins/Options/skip.ts: -------------------------------------------------------------------------------- 1 | import { IOperation } from '@nishans/types'; 2 | import { CommonPluginOptions } from '../../types'; 3 | 4 | /** 5 | * Skip a certain operation based on the return value of a callback 6 | * @param skipFn The callback to be invoked to determine whether a operation should be skipped or not 7 | * @param operation The operation is question 8 | */ 9 | export function skipOption (operation: IOperation, skipFn?: CommonPluginOptions['skip']) { 10 | let should_skip = false; 11 | if (skipFn) should_skip = skipFn(operation); 12 | if (should_skip) return operation; 13 | } 14 | -------------------------------------------------------------------------------- /packages/operations/libs/Plugins/index.ts: -------------------------------------------------------------------------------- 1 | import { removeEmptyOperationsPlugin } from './removeEmptyOperationsPlugin'; 2 | import { removeLastEditedPropsPlugin } from './removeLastEditedPropsPlugin'; 3 | import { validateOperationsPlugin } from './validateOperationsPlugin'; 4 | 5 | export const NotionOperationsPlugin = { 6 | validateOperations: validateOperationsPlugin, 7 | removeLastEditedProps: removeLastEditedPropsPlugin, 8 | removeEmptyOperations: removeEmptyOperationsPlugin 9 | }; 10 | -------------------------------------------------------------------------------- /packages/operations/libs/index.ts: -------------------------------------------------------------------------------- 1 | import { applyPluginsToOperationsStack } from './applyPluginsToOperationsStack'; 2 | import { NotionOperationsChunk } from './Chunk'; 3 | import { executeOperations } from './executeOperations'; 4 | import { NotionOperationsPlugin } from './Plugins'; 5 | 6 | export * from './types'; 7 | 8 | export const NotionOperations = { 9 | executeOperations, 10 | applyPluginsToOperationsStack, 11 | Plugin: NotionOperationsPlugin, 12 | Chunk: NotionOperationsChunk 13 | }; 14 | -------------------------------------------------------------------------------- /packages/operations/libs/types.ts: -------------------------------------------------------------------------------- 1 | import { INotionEndpointsOptions } from '@nishans/endpoints'; 2 | import { IOperation } from '@nishans/types'; 3 | 4 | export interface CommonPluginOptions { 5 | skip?: (operation: IOperation) => boolean; 6 | } 7 | 8 | export type NotionOperationPluginFactory< 9 | T extends CommonPluginOptions = CommonPluginOptions 10 | > = (options?: T) => NotionOperationPluginFunction; 11 | export type NotionOperationPluginFunction = ( 12 | operation: IOperation 13 | ) => false | IOperation; 14 | 15 | export type INotionOperationOptions = INotionEndpointsOptions & { 16 | notion_operation_plugins?: NotionOperationPluginFunction[]; 17 | space_id: string; 18 | }; 19 | -------------------------------------------------------------------------------- /packages/operations/tests/Chunk/Operations.test.ts: -------------------------------------------------------------------------------- 1 | import { NotionOperations } from '../../libs'; 2 | 3 | describe('Operation', () => { 4 | it(`Should return correct operation`, () => { 5 | expect( 6 | NotionOperations.Chunk.block.update('123', 'spaceId', ['pages'], {}) 7 | ).toStrictEqual({ 8 | pointer: { 9 | table: 'block', 10 | id: '123', 11 | spaceId: 'spaceId' 12 | }, 13 | path: ['pages'], 14 | command: 'update', 15 | args: {} 16 | }); 17 | }); 18 | }); 19 | -------------------------------------------------------------------------------- /packages/operations/tests/utils.ts: -------------------------------------------------------------------------------- 1 | import { IOperation } from '@nishans/types'; 2 | 3 | export const operation: IOperation = { 4 | args: {}, 5 | command: 'update', 6 | pointer: { 7 | table: 'block', 8 | id: '123' 9 | }, 10 | path: [] 11 | }; 12 | 13 | export const common_execute_operations_options = { 14 | notion_operation_plugins: [], 15 | token: 'token', 16 | 17 | space_id: 'space_1', 18 | user_id: 'user_root_1' 19 | }; 20 | -------------------------------------------------------------------------------- /packages/operations/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.shared.json", 3 | "include": [ 4 | "./libs/index.ts", 5 | "./experiment" 6 | ], 7 | "compilerOptions": { 8 | "outDir": "./dist", 9 | "rootDir": "./" 10 | } 11 | } -------------------------------------------------------------------------------- /packages/orm/libs/Db/getTables.ts: -------------------------------------------------------------------------------- 1 | import { NotionCore } from '@nishans/core'; 2 | 3 | export async function getTables(db: InstanceType) { 4 | const block_map = await db.getBlocks( 5 | (block) => block.type === 'collection_view_page' 6 | ); 7 | return block_map.collection_view_page; 8 | } 9 | -------------------------------------------------------------------------------- /packages/orm/libs/Db/index.ts: -------------------------------------------------------------------------------- 1 | import { createDbs } from './createDbs'; 2 | import { deleteDbs } from './deleteDbs'; 3 | import { getTables } from './getTables'; 4 | import { updateDbs } from './updateDbs'; 5 | 6 | export const NotionOrmDb = { 7 | create: createDbs, 8 | getTables: getTables, 9 | delete: deleteDbs, 10 | update: updateDbs 11 | }; 12 | -------------------------------------------------------------------------------- /packages/orm/libs/Table/deleteTables.ts: -------------------------------------------------------------------------------- 1 | import { NotionCore } from '@nishans/core'; 2 | 3 | export async function deleteTables( 4 | tableNames: string[], 5 | db: InstanceType 6 | ) { 7 | await db.deleteBlocks((block) => { 8 | if (block.type === 'collection_view_page') { 9 | const collection = db.cache.collection.get(block.collection_id)!; 10 | return tableNames.includes(collection.name[0][0]); 11 | } 12 | }); 13 | } 14 | -------------------------------------------------------------------------------- /packages/orm/libs/Table/index.ts: -------------------------------------------------------------------------------- 1 | import { createTables } from './createTables'; 2 | import { deleteTables } from './deleteTables'; 3 | 4 | export const NotionOrmTable = { 5 | create: createTables, 6 | delete: deleteTables 7 | }; 8 | -------------------------------------------------------------------------------- /packages/orm/libs/index.ts: -------------------------------------------------------------------------------- 1 | import { NotionOrmDb } from './Db'; 2 | import { NotionOrmTable } from './Table'; 3 | 4 | export const NotionOrm = { 5 | Db: NotionOrmDb, 6 | Table: NotionOrmTable 7 | }; 8 | 9 | export * from './types'; 10 | -------------------------------------------------------------------------------- /packages/orm/libs/types.ts: -------------------------------------------------------------------------------- 1 | import { ICollectionBlockInput } from '@nishans/fabricator'; 2 | 3 | export interface ITableInfo { 4 | name: string; 5 | schema: ICollectionBlockInput['schema']; 6 | } 7 | -------------------------------------------------------------------------------- /packages/orm/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.shared.json", 3 | "include": [ 4 | "./libs/index.ts", 5 | "./experiment" 6 | ], 7 | "compilerOptions": { 8 | "outDir": "./dist", 9 | "rootDir": "./" 10 | } 11 | } -------------------------------------------------------------------------------- /packages/permissions/libs/index.ts: -------------------------------------------------------------------------------- 1 | import { NotionBlockPermissions } from './BlockPermissions'; 2 | import { NotionSpacePermissions } from './SpacePermissions'; 3 | 4 | export const NotionPermissions = { 5 | Block: NotionBlockPermissions, 6 | Space: NotionSpacePermissions 7 | }; 8 | -------------------------------------------------------------------------------- /packages/permissions/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.shared.json", 3 | "include": [ 4 | "./libs/index.ts", 5 | "./experiment", 6 | "./examples" 7 | ], 8 | "compilerOptions": { 9 | "outDir": "./dist", 10 | "rootDir": "./", 11 | }, 12 | } -------------------------------------------------------------------------------- /packages/react-filters/.env: -------------------------------------------------------------------------------- 1 | SKIP_PREFLIGHT_CHECK=true 2 | -------------------------------------------------------------------------------- /packages/react-filters/.storybook/main.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "stories": [ 3 | "../src/**/*.stories.mdx", 4 | "../src/**/*.stories.@(js|jsx|ts|tsx)" 5 | ], 6 | "addons": [ 7 | "@storybook/addon-links", 8 | "@storybook/addon-essentials" 9 | ] 10 | } -------------------------------------------------------------------------------- /packages/react-filters/.storybook/preview.js: -------------------------------------------------------------------------------- 1 | 2 | export const parameters = { 3 | actions: { argTypesRegex: "^on[A-Z].*" }, 4 | } -------------------------------------------------------------------------------- /packages/react-filters/src/components/Shared/index.ts: -------------------------------------------------------------------------------- 1 | export * from './BasicSelect'; 2 | -------------------------------------------------------------------------------- /packages/react-filters/src/globalTheme.ts: -------------------------------------------------------------------------------- 1 | import { createMuiTheme } from '@material-ui/core/styles'; 2 | 3 | export default createMuiTheme({ 4 | typography: { 5 | fontFamily: [ 'Segoe UI' ].join(',') 6 | }, 7 | overrides: { 8 | MuiOutlinedInput: { 9 | input: { 10 | padding: 5 11 | } 12 | }, 13 | MuiFormControl: { 14 | root: { 15 | justifyContent: 'center', 16 | width: "100%" 17 | } 18 | } 19 | } 20 | }); 21 | -------------------------------------------------------------------------------- /packages/react-filters/src/react-app-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /packages/react-filters/src/setupTests.ts: -------------------------------------------------------------------------------- 1 | // jest-dom adds custom jest matchers for asserting on DOM nodes. 2 | // allows you to do things like: 3 | // expect(element).toHaveTextContent(/react/i) 4 | // learn more: https://github.com/testing-library/jest-dom 5 | import '@testing-library/jest-dom'; 6 | -------------------------------------------------------------------------------- /packages/react-filters/src/stories/Header.stories.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | // also exported from '@storybook/react' if you can deal with breaking changes in 6.1 3 | import { Story, Meta } from '@storybook/react/types-6-0'; 4 | 5 | import { Header, HeaderProps } from './Header'; 6 | 7 | export default { 8 | title: 'Example/Header', 9 | component: Header, 10 | } as Meta; 11 | 12 | const Template: Story = (args) =>
; 13 | 14 | export const LoggedIn = Template.bind({}); 15 | LoggedIn.args = { 16 | user: {}, 17 | }; 18 | 19 | export const LoggedOut = Template.bind({}); 20 | LoggedOut.args = {}; 21 | -------------------------------------------------------------------------------- /packages/react-filters/src/stories/Page.stories.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | // also exported from '@storybook/react' if you can deal with breaking changes in 6.1 3 | import { Story, Meta } from '@storybook/react/types-6-0'; 4 | 5 | import { Page, PageProps } from './Page'; 6 | import * as HeaderStories from './Header.stories'; 7 | 8 | export default { 9 | title: 'Example/Page', 10 | component: Page, 11 | } as Meta; 12 | 13 | const Template: Story = (args) => ; 14 | 15 | export const LoggedIn = Template.bind({}); 16 | LoggedIn.args = { 17 | ...HeaderStories.LoggedIn.args, 18 | }; 19 | 20 | export const LoggedOut = Template.bind({}); 21 | LoggedOut.args = { 22 | ...HeaderStories.LoggedOut.args, 23 | }; 24 | -------------------------------------------------------------------------------- /packages/react-filters/src/stories/header.css: -------------------------------------------------------------------------------- 1 | .wrapper { 2 | font-family: 'Nunito Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif; 3 | border-bottom: 1px solid rgba(0, 0, 0, 0.1); 4 | padding: 15px 20px; 5 | display: flex; 6 | align-items: center; 7 | justify-content: space-between; 8 | } 9 | 10 | svg { 11 | display: inline-block; 12 | vertical-align: top; 13 | } 14 | 15 | h1 { 16 | font-weight: 900; 17 | font-size: 20px; 18 | line-height: 1; 19 | margin: 6px 0 6px 10px; 20 | display: inline-block; 21 | vertical-align: top; 22 | } 23 | 24 | button + button { 25 | margin-left: 10px; 26 | } 27 | -------------------------------------------------------------------------------- /packages/react-filters/src/types.ts: -------------------------------------------------------------------------------- 1 | import { IViewFilter, SelectOption, TSchemaUnitType } from '@nishans/types'; 2 | 3 | export type TSchemaInfo = [TSchemaUnitType, string, string][]; 4 | 5 | export type TFilterItemValue = 6 | | 'string' 7 | | 'checkbox' 8 | | 'date' 9 | | 'number' 10 | | 'options' 11 | | SelectOption[] 12 | | { value: string; label: string }[] 13 | | null; 14 | 15 | export interface FilterGroupProps { 16 | filter: IViewFilter; 17 | trails: number[]; 18 | parent_filter: IViewFilter | null; 19 | } 20 | -------------------------------------------------------------------------------- /packages/react-filters/src/utils/convertIntoSelectMenuItem.ts: -------------------------------------------------------------------------------- 1 | export function convertIntoSelectMenuItem ( 2 | label: string 3 | ): { 4 | label: string; 5 | value: any; 6 | } { 7 | return { 8 | label, 9 | value: label.toLowerCase().split(' ').join('_') 10 | }; 11 | } 12 | 13 | export function convertIntoSelectMenuItems (labels: string[]) { 14 | return labels.map(convertIntoSelectMenuItem); 15 | } 16 | -------------------------------------------------------------------------------- /packages/react-filters/src/utils/createFilterLiterals.ts: -------------------------------------------------------------------------------- 1 | import { TViewFilters, TViewGroupFilterOperator, IViewFilter } from "@nishans/types"; 2 | 3 | export const createEmptyFilter = (): TViewFilters => ({ 4 | property: 'title', 5 | filter: { 6 | operator: 'string_is', 7 | value: { 8 | type: 'exact', 9 | value: '' 10 | } 11 | } 12 | }); 13 | 14 | export const createEmptyFilterGroup = (operator?: TViewGroupFilterOperator, filters?: (TViewFilters | IViewFilter)[]): any => ({ 15 | filters: filters ?? [], 16 | operator: operator ?? 'and' 17 | }); 18 | -------------------------------------------------------------------------------- /packages/react-filters/src/utils/orderSchema.ts: -------------------------------------------------------------------------------- 1 | import { Schema, TSchemaUnit } from '@nishans/types'; 2 | 3 | export function orderSchema (schema: Schema): (TSchemaUnit & { schema_id: string })[] { 4 | return Object.entries(schema) 5 | .sort(([ keyA, valueA ], [ keyB, valueB ]) => (valueA.name < valueB.name ? -1 : 1)) 6 | .map(([ key, value ]) => ({ ...value, schema_id: key })); 7 | } 8 | -------------------------------------------------------------------------------- /packages/react-filters/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ESNext", 4 | "lib": [ 5 | "dom", 6 | "dom.iterable", 7 | "esnext" 8 | ], 9 | "allowJs": true, 10 | "skipLibCheck": true, 11 | "esModuleInterop": true, 12 | "allowSyntheticDefaultImports": true, 13 | "strict": true, 14 | "forceConsistentCasingInFileNames": true, 15 | "noFallthroughCasesInSwitch": true, 16 | "module": "esnext", 17 | "moduleResolution": "node", 18 | "resolveJsonModule": true, 19 | "isolatedModules": true, 20 | "noEmit": true, 21 | "jsx": "react-jsx" 22 | }, 23 | "include": [ 24 | "src" 25 | ] 26 | } -------------------------------------------------------------------------------- /packages/remark-notion/src/types.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Devorein/Nishan/5c258d07d6a5a9ea45a3b44ec04eb19018f4deda/packages/remark-notion/src/types.ts -------------------------------------------------------------------------------- /packages/schema-builder/src/index.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Devorein/Nishan/5c258d07d6a5a9ea45a3b44ec04eb19018f4deda/packages/schema-builder/src/index.ts -------------------------------------------------------------------------------- /packages/schema-builder/src/types.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Devorein/Nishan/5c258d07d6a5a9ea45a3b44ec04eb19018f4deda/packages/schema-builder/src/types.ts -------------------------------------------------------------------------------- /packages/schema-builder/utils/index.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Devorein/Nishan/5c258d07d6a5a9ea45a3b44ec04eb19018f4deda/packages/schema-builder/utils/index.ts -------------------------------------------------------------------------------- /packages/sync/libs/Read/index.ts: -------------------------------------------------------------------------------- 1 | import { readFromFile } from './readFromFile'; 2 | import { readFromMongodb } from './readFromMongodb'; 3 | import { readFromNotion } from './readFromNotion'; 4 | 5 | export const NotionSyncRead = { 6 | fromFile: readFromFile, 7 | fromMongodb: readFromMongodb, 8 | fromNotion: readFromNotion 9 | }; 10 | -------------------------------------------------------------------------------- /packages/sync/libs/Restore/fromFile.ts: -------------------------------------------------------------------------------- 1 | import { INotionOperationOptions } from '@nishans/operations'; 2 | import { NotionSync } from '../'; 3 | 4 | /** 5 | * Restore notion from data stored in local file 6 | * @param filepath Absolute file path of the local file 7 | * @param options Notion Operations Options 8 | */ 9 | export async function notionSyncRestoreFromFile (filepath: string, options: INotionOperationOptions) { 10 | await NotionSync.Write.toNotion(await NotionSync.Read.fromFile(filepath), options); 11 | } 12 | -------------------------------------------------------------------------------- /packages/sync/libs/Restore/fromMongodb.ts: -------------------------------------------------------------------------------- 1 | import { INotionOperationOptions } from '@nishans/operations'; 2 | import { NotionSync } from '../'; 3 | 4 | /** 5 | * Restore notion from data stored in local or remote mongodb instance 6 | * @param connection_uri Connection uri of the remote or local mongodb instance 7 | * @param options Notion Operations Options 8 | */ 9 | export async function notionSyncRestoreFromMongodb (connection_uri: string, options: INotionOperationOptions) { 10 | await NotionSync.Write.toNotion(await NotionSync.Read.fromMongodb(connection_uri), options); 11 | } 12 | -------------------------------------------------------------------------------- /packages/sync/libs/Restore/index.ts: -------------------------------------------------------------------------------- 1 | import { notionSyncRestoreFromFile } from './fromFile'; 2 | import { notionSyncRestoreFromMongodb } from './fromMongodb'; 3 | 4 | export const NotionSyncRestore = { 5 | fromFile: notionSyncRestoreFromFile, 6 | fromMongodb: notionSyncRestoreFromMongodb 7 | }; 8 | -------------------------------------------------------------------------------- /packages/sync/libs/Store/File/fromMongodb.ts: -------------------------------------------------------------------------------- 1 | import { NotionSync } from '../../'; 2 | 3 | /** 4 | * Stores data from remote/local mongodb instance into a local file 5 | * @param connection_uri Connection uri of the local or remote mongodb instance 6 | * @param filepath full path of the output file 7 | */ 8 | export async function storeInFileFromMongodb (connection_uri: string, filepath: string) { 9 | await NotionSync.Write.toFile(filepath, await NotionSync.Read.fromMongodb(connection_uri)); 10 | } 11 | -------------------------------------------------------------------------------- /packages/sync/libs/Store/File/fromNotion.ts: -------------------------------------------------------------------------------- 1 | import { INotionCacheOptions } from '@nishans/cache'; 2 | import { NotionSync } from '../../'; 3 | 4 | /** 5 | * Stores data from notion collection block into a local file 6 | * @param database_id Id of the notion collection block 7 | * @param filepath full path of the output file 8 | * @param options Notion Cache options 9 | */ 10 | export async function storeInFileFromNotion (database_id: string, filepath: string, options: INotionCacheOptions) { 11 | await NotionSync.Write.toFile(filepath, await NotionSync.Read.fromNotion(database_id, options)); 12 | } 13 | -------------------------------------------------------------------------------- /packages/sync/libs/Store/File/index.ts: -------------------------------------------------------------------------------- 1 | import { storeInFileFromMongodb } from './fromMongodb'; 2 | import { storeInFileFromNotion } from './fromNotion'; 3 | 4 | export const NotionSyncFileStore = { 5 | fromMongodb: storeInFileFromMongodb, 6 | fromNotion: storeInFileFromNotion 7 | }; 8 | -------------------------------------------------------------------------------- /packages/sync/libs/Store/Mongodb/fromFile.ts: -------------------------------------------------------------------------------- 1 | import { NotionSync } from '../../'; 2 | 3 | /** 4 | * Stores data from local file from file system into local/remote mongodb instance 5 | * @param connection_uri Connection uri of the mongodb instance 6 | * @param file_path Full path to the output file 7 | */ 8 | export async function storeInMongodbFromFile (connection_uri: string, file_path: string) { 9 | await NotionSync.Write.toMongodb(connection_uri, await NotionSync.Read.fromFile(file_path)); 10 | } 11 | -------------------------------------------------------------------------------- /packages/sync/libs/Store/Mongodb/fromNotion.ts: -------------------------------------------------------------------------------- 1 | import { INotionCacheOptions } from '@nishans/cache'; 2 | import { NotionSync } from '../../'; 3 | 4 | /** 5 | * Stores data from notion collection block into local/remote mongodb instance 6 | * @param connection_uri Mongodb connection uri 7 | * @param database_id Id of the notion database 8 | * @param options Notion Cache options 9 | */ 10 | export async function storeInMongodbFromNotion ( 11 | connection_uri: string, 12 | database_id: string, 13 | options: INotionCacheOptions 14 | ) { 15 | await NotionSync.Write.toMongodb(connection_uri, await NotionSync.Read.fromNotion(database_id, options)); 16 | } 17 | -------------------------------------------------------------------------------- /packages/sync/libs/Store/Mongodb/index.ts: -------------------------------------------------------------------------------- 1 | import { storeInMongodbFromFile } from './fromFile'; 2 | import { storeInMongodbFromNotion } from './fromNotion'; 3 | 4 | export const NotionSyncMongodbStore = { 5 | fromFile: storeInMongodbFromFile, 6 | fromNotion: storeInMongodbFromNotion 7 | }; 8 | -------------------------------------------------------------------------------- /packages/sync/libs/Store/index.ts: -------------------------------------------------------------------------------- 1 | import { NotionSyncFileStore } from './File'; 2 | import { NotionSyncMongodbStore } from './Mongodb'; 3 | 4 | export const NotionSyncStore = { 5 | InFile: NotionSyncFileStore, 6 | InMongodb: NotionSyncMongodbStore 7 | }; 8 | -------------------------------------------------------------------------------- /packages/sync/libs/Write/index.ts: -------------------------------------------------------------------------------- 1 | import { writeToFile } from './writeToFile'; 2 | import { writeToMongodb } from './writeToMongodb'; 3 | import { writeToNotion } from './writeToNotion'; 4 | 5 | export const NotionSyncWrite = { 6 | toFile: writeToFile, 7 | toMongodb: writeToMongodb, 8 | toNotion: writeToNotion 9 | }; 10 | -------------------------------------------------------------------------------- /packages/sync/libs/index.ts: -------------------------------------------------------------------------------- 1 | import { extractData } from './extractData'; 2 | import { NotionSyncRead } from './Read'; 3 | import { NotionSyncRestore } from './Restore'; 4 | import { NotionSyncStore } from './Store'; 5 | import { NotionSyncWrite } from './Write'; 6 | 7 | export * from './types'; 8 | 9 | export const NotionSync = { 10 | extractData, 11 | Store: NotionSyncStore, 12 | Restore: NotionSyncRestore, 13 | Write: NotionSyncWrite, 14 | Read: NotionSyncRead 15 | }; 16 | -------------------------------------------------------------------------------- /packages/sync/libs/types.ts: -------------------------------------------------------------------------------- 1 | import { CollectionExtracted, PageExtracted, TViewExtracted } from '@nishans/extract'; 2 | export interface INotionSyncFileShape { 3 | views: TViewExtracted[]; 4 | collection: CollectionExtracted; 5 | row_pages: PageExtracted[]; 6 | template_pages: PageExtracted[]; 7 | } 8 | -------------------------------------------------------------------------------- /packages/sync/tests/Restore/fromFile.test.ts: -------------------------------------------------------------------------------- 1 | import { NotionSync } from '../../libs'; 2 | 3 | afterEach(() => { 4 | jest.restoreAllMocks(); 5 | }); 6 | 7 | it(`restoreFromFile`, async () => { 8 | const writeToNotionMock = jest.spyOn(NotionSync.Write, 'toNotion').mockImplementationOnce(async () => undefined), 9 | readFromFileMock = jest.spyOn(NotionSync.Read, 'fromFile').mockImplementationOnce(async () => ({} as any)); 10 | 11 | await NotionSync.Restore.fromFile('data.json', {} as any); 12 | 13 | expect(writeToNotionMock).toHaveBeenCalledTimes(1); 14 | expect(readFromFileMock).toHaveBeenCalledTimes(1); 15 | }); 16 | -------------------------------------------------------------------------------- /packages/sync/tests/Restore/fromMongodb.test.ts: -------------------------------------------------------------------------------- 1 | import { NotionSync } from '../../libs'; 2 | 3 | afterEach(() => { 4 | jest.restoreAllMocks(); 5 | }); 6 | 7 | it(`restoreFromMongodb`, async () => { 8 | const writeToNotionMock = jest.spyOn(NotionSync.Write, 'toNotion').mockImplementationOnce(async () => undefined), 9 | readFromMongodbMock = jest.spyOn(NotionSync.Read, 'fromMongodb').mockImplementationOnce(async () => ({} as any)); 10 | 11 | await NotionSync.Restore.fromMongodb('connection_uri', {} as any); 12 | 13 | expect(writeToNotionMock).toHaveBeenCalledTimes(1); 14 | expect(readFromMongodbMock).toHaveBeenCalledTimes(1); 15 | }); 16 | -------------------------------------------------------------------------------- /packages/sync/tests/Store/File/fromMongodb.test.ts: -------------------------------------------------------------------------------- 1 | import { NotionSync } from '../../../libs'; 2 | 3 | afterEach(() => { 4 | jest.restoreAllMocks(); 5 | }); 6 | 7 | it(`storeInFileFromMongodb`, async () => { 8 | const writeToFileMock = jest.spyOn(NotionSync.Write, 'toFile').mockImplementationOnce(async () => undefined), 9 | readFromMongodbMock = jest.spyOn(NotionSync.Read, 'fromMongodb').mockImplementationOnce(async () => ({} as any)); 10 | 11 | await NotionSync.Store.InFile.fromMongodb('connection_uri', 'data.json'); 12 | 13 | expect(writeToFileMock).toHaveBeenCalledTimes(1); 14 | expect(readFromMongodbMock).toHaveBeenCalledTimes(1); 15 | }); 16 | -------------------------------------------------------------------------------- /packages/sync/tests/Store/File/fromNotion.test.ts: -------------------------------------------------------------------------------- 1 | import { NotionSync } from '../../../libs'; 2 | 3 | afterEach(() => { 4 | jest.restoreAllMocks(); 5 | }); 6 | 7 | it(`storeInFileFromNotion`, async () => { 8 | const writeToFileMock = jest.spyOn(NotionSync.Write, 'toFile').mockImplementationOnce(async () => undefined), 9 | readFromNotionMock = jest.spyOn(NotionSync.Read, 'fromNotion').mockImplementationOnce(async () => ({} as any)); 10 | 11 | await NotionSync.Store.InFile.fromNotion('database_id', 'data.json', {} as any); 12 | 13 | expect(writeToFileMock).toHaveBeenCalledTimes(1); 14 | expect(readFromNotionMock).toHaveBeenCalledTimes(1); 15 | }); 16 | -------------------------------------------------------------------------------- /packages/sync/tests/Store/Mongodb/fromFile.test.ts: -------------------------------------------------------------------------------- 1 | import { NotionSync } from '../../../libs'; 2 | 3 | it(`storeInMongodbFromAtlas`, async () => { 4 | const writeToMongodbMock = jest.spyOn(NotionSync.Write, 'toMongodb').mockImplementationOnce(async () => undefined), 5 | readFromFileMock = jest.spyOn(NotionSync.Read, 'fromFile').mockImplementationOnce(async () => ({} as any)); 6 | 7 | await NotionSync.Store.InMongodb.fromFile('database_id', {} as any); 8 | 9 | expect(writeToMongodbMock).toHaveBeenCalledTimes(1); 10 | expect(readFromFileMock).toHaveBeenCalledTimes(1); 11 | }); 12 | -------------------------------------------------------------------------------- /packages/sync/tests/Store/Mongodb/fromNotion.test.ts: -------------------------------------------------------------------------------- 1 | import { NotionSync } from '../../../libs'; 2 | 3 | it(`storeInMongodbFromNotion`, async () => { 4 | const writeToMongodbMock = jest.spyOn(NotionSync.Write, 'toMongodb').mockImplementationOnce(async () => undefined), 5 | readFromNotionMock = jest.spyOn(NotionSync.Read, 'fromNotion').mockImplementationOnce(async () => ({} as any)); 6 | 7 | await NotionSync.Store.InMongodb.fromNotion('connection_uri', 'database_id', {} as any); 8 | 9 | expect(writeToMongodbMock).toHaveBeenCalledTimes(1); 10 | expect(readFromNotionMock).toHaveBeenCalledTimes(1); 11 | }); 12 | -------------------------------------------------------------------------------- /packages/sync/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.shared.json", 3 | "include": [ 4 | "./libs/index.ts", 5 | "./experiment", 6 | "./examples" 7 | ], 8 | "compilerOptions": { 9 | "outDir": "./dist", 10 | "rootDir": "./", 11 | }, 12 | } -------------------------------------------------------------------------------- /packages/tasks/libs/Export/index.ts: -------------------------------------------------------------------------------- 1 | import { exportBlock } from './exportBlock'; 2 | import { exportSpace } from './exportSpace'; 3 | 4 | export const ExportTask = { 5 | block: exportBlock, 6 | space: exportSpace 7 | }; 8 | -------------------------------------------------------------------------------- /packages/tasks/libs/importFile.ts: -------------------------------------------------------------------------------- 1 | import { INotionEndpointsOptions } from '@nishans/endpoints'; 2 | import { TImportFileTaskPayload } from '@nishans/types'; 3 | import { NotionTasks } from '../libs'; 4 | 5 | export const importFile = async ( 6 | request: TImportFileTaskPayload['task']['request'], 7 | options: INotionEndpointsOptions 8 | ) => { 9 | await NotionTasks.enqueueAndPollTask<'importFile'>( 10 | { 11 | task: { 12 | eventName: 'importFile', 13 | request 14 | } as any 15 | }, 16 | {}, 17 | options 18 | ); 19 | }; 20 | -------------------------------------------------------------------------------- /packages/tasks/libs/index.ts: -------------------------------------------------------------------------------- 1 | import { enqueueAndPollTask } from './enqueueAndPollTask'; 2 | import { ExportTask } from './Export'; 3 | import { importFile } from './importFile'; 4 | 5 | export const NotionTasks = { 6 | Export: ExportTask, 7 | importFile, 8 | enqueueAndPollTask 9 | }; 10 | -------------------------------------------------------------------------------- /packages/tasks/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.shared.json", 3 | "include": [ 4 | "./libs/index.ts", 5 | "./experiment" 6 | ], 7 | "compilerOptions": { 8 | "outDir": "./dist", 9 | "rootDir": "./" 10 | } 11 | } -------------------------------------------------------------------------------- /packages/traverser/libs/index.ts: -------------------------------------------------------------------------------- 1 | import { remove } from './delete'; 2 | import { get } from './get'; 3 | import { update } from './update'; 4 | 5 | export const NotionTraverser = { 6 | get, 7 | update, 8 | delete: remove 9 | }; 10 | 11 | export * from './types'; 12 | -------------------------------------------------------------------------------- /packages/traverser/libs/utils/getChildIds.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Get child id container from a parent 3 | * @param child_ids Child path or array of child ids 4 | * @param parent_data parent data to lookup for child id 5 | */ 6 | export function getChildIds (child_ids: keyof T | string[], parent_data: T) { 7 | return (Array.isArray(child_ids) ? child_ids : parent_data[child_ids]) as string[]; 8 | } 9 | -------------------------------------------------------------------------------- /packages/traverser/libs/utils/index.ts: -------------------------------------------------------------------------------- 1 | export * from './getChildIds'; 2 | export * from './iterateChildren'; 3 | -------------------------------------------------------------------------------- /packages/traverser/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.shared.json", 3 | "include": [ 4 | "./libs/index.ts", 5 | "./experiment", 6 | "./examples" 7 | ], 8 | "compilerOptions": { 9 | "outDir": "./dist", 10 | "rootDir": "./", 11 | }, 12 | } -------------------------------------------------------------------------------- /packages/typegen/libs/index.ts: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = typegen; 4 | 5 | function typegen() { 6 | // TODO 7 | } 8 | -------------------------------------------------------------------------------- /packages/typegen/libs/types.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Devorein/Nishan/5c258d07d6a5a9ea45a3b44ec04eb19018f4deda/packages/typegen/libs/types.ts -------------------------------------------------------------------------------- /packages/typegen/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "lib": [ 4 | "ESNext", 5 | "dom", 6 | ], 7 | "baseUrl": "./", 8 | "module": "commonjs", 9 | "moduleResolution": "node", 10 | "target": "ES2015", 11 | "strict": true, 12 | "esModuleInterop": true, 13 | "skipLibCheck": true, 14 | "forceConsistentCasingInFileNames": true, 15 | "outDir": "./dist", 16 | "watch": false, 17 | "declaration": true, 18 | "sourceMap": false, 19 | "noUnusedLocals": false, 20 | "incremental": false 21 | }, 22 | "include": [ 23 | "./src/index.ts", 24 | "experiment" 25 | ], 26 | "exclude": [ 27 | "./node_modules", 28 | ] 29 | } -------------------------------------------------------------------------------- /packages/types/libs/color.ts: -------------------------------------------------------------------------------- 1 | export type TTextColor = 2 | | 'default' 3 | | 'gray' 4 | | 'brown' 5 | | 'orange' 6 | | 'yellow' 7 | | 'teal' 8 | | 'blue' 9 | | 'purple' 10 | | 'pink' 11 | | 'red'; 12 | export type TBGColor = 13 | | 'default_background' 14 | | 'gray_background' 15 | | 'brown_background' 16 | | 'orange_background' 17 | | 'yellow_background' 18 | | 'teal_background' 19 | | 'blue_background' 20 | | 'purple_background' 21 | | 'pink_background' 22 | | 'red_background'; 23 | export type TFormatBlockColor = TTextColor | TBGColor; 24 | -------------------------------------------------------------------------------- /packages/types/libs/index.ts: -------------------------------------------------------------------------------- 1 | export * from './activity'; 2 | export * from './aggregator'; 3 | export * from './block'; 4 | export * from './color'; 5 | export * from './credit'; 6 | export * from './date'; 7 | export * from './endpoints'; 8 | export * from './error'; 9 | export * from './filter'; 10 | export * from './formula'; 11 | export * from './inlineformat'; 12 | export * from './notifications'; 13 | export * from './operation'; 14 | export * from './permissions'; 15 | export * from './recordMap'; 16 | export * from './schema'; 17 | export * from './search'; 18 | export * from './shared'; 19 | export * from './subscription'; 20 | export * from './tasks'; 21 | export * from './types'; 22 | export * from './view'; 23 | -------------------------------------------------------------------------------- /packages/types/libs/operation.ts: -------------------------------------------------------------------------------- 1 | import { TDataType } from './types'; 2 | 3 | export type TOperationCommand = 4 | | 'set' 5 | | 'update' 6 | | 'keyedObjectListAfter' 7 | | 'keyedObjectListUpdate' 8 | | 'listAfter' 9 | | 'listRemove' 10 | | 'listBefore' 11 | | 'setPermissionItem'; 12 | 13 | export interface Transaction { 14 | id: string; 15 | spaceId: string; 16 | operations: IOperation[]; 17 | } 18 | 19 | export interface IPointer { 20 | table: TDataType; 21 | id: string; 22 | spaceId: string; 23 | } 24 | export interface IOperation { 25 | pointer: IPointer; 26 | command: TOperationCommand; 27 | path: string[]; 28 | args: any; 29 | } 30 | -------------------------------------------------------------------------------- /packages/types/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.shared.json", 3 | "include": [ 4 | "./libs/index.ts", 5 | "./experiment" 6 | ], 7 | "compilerOptions": { 8 | "outDir": "./dist", 9 | "rootDir": "./" 10 | } 11 | } -------------------------------------------------------------------------------- /packages/utils/libs/extractInlineBlockContent.ts: -------------------------------------------------------------------------------- 1 | import { TTextFormat } from '@nishans/types'; 2 | 3 | export function extractInlineBlockContent (inline_block: TTextFormat) { 4 | return inline_block.reduce((prev, current) => prev + current[0], ''); 5 | } 6 | -------------------------------------------------------------------------------- /packages/utils/libs/generateSchemaMap.ts: -------------------------------------------------------------------------------- 1 | import { ISchemaMap, Schema } from '@nishans/types'; 2 | 3 | /** 4 | * Generates a schema_map from the passed schema 5 | * @param schema The collection schema used to generate the schema_map 6 | * @returns The generated schema map 7 | */ 8 | export function generateSchemaMap (schema: Schema) { 9 | const schema_map: ISchemaMap = new Map(); 10 | // Map through each key of the passed schema and use its name property to act as a key to the map 11 | Object.entries(schema).forEach(([ schema_id, value ]) => { 12 | schema_map.set(value.name, { 13 | schema_id, 14 | ...value 15 | }); 16 | }); 17 | return schema_map; 18 | } 19 | -------------------------------------------------------------------------------- /packages/utils/libs/getSchemaMapUnit.ts: -------------------------------------------------------------------------------- 1 | import { NotionErrors } from '@nishans/errors'; 2 | import { ISchemaMap } from '@nishans/types'; 3 | 4 | export const getSchemaMapUnit = (schema_map: ISchemaMap, key: string, path: string[]) => { 5 | const schema_map_unit = schema_map.get(key); 6 | if (schema_map_unit) return schema_map_unit; 7 | else throw new NotionErrors.unknown_property_reference(key, path); 8 | }; 9 | -------------------------------------------------------------------------------- /packages/utils/libs/getSchemaUnit.ts: -------------------------------------------------------------------------------- 1 | import { NotionErrors } from '@nishans/errors'; 2 | import { Schema } from '@nishans/types'; 3 | 4 | export const getSchemaUnit = (schema: Schema, name: string, path: string[]) => { 5 | const schema_unit = schema[name]; 6 | if (schema_unit) return schema_unit; 7 | else throw new NotionErrors.unknown_property_reference(name, path); 8 | }; 9 | -------------------------------------------------------------------------------- /packages/utils/libs/populateChildPath.ts: -------------------------------------------------------------------------------- 1 | import { TData } from '@nishans/types'; 2 | 3 | export const populateChildPath = (arg: { data: T; child_path: keyof T; child_id: string }) => { 4 | const { data, child_id, child_path } = arg; 5 | if (!data[child_path]) data[child_path] = [ child_id ] as any; 6 | else (data[child_path] as any).push(child_id); 7 | }; 8 | -------------------------------------------------------------------------------- /packages/utils/libs/setDefault.ts: -------------------------------------------------------------------------------- 1 | function isObject (item: any) { 2 | return item && typeof item === 'object' && !Array.isArray(item); 3 | } 4 | 5 | export function setDefault (target: Record, source: Record) { 6 | Object.keys(source).forEach((key) => { 7 | if (isObject(source[key])) target[key] = setDefault(target[key] ?? {}, source[key]); 8 | else if (!(key in target)) Object.assign(target, { [key]: source[key] }); 9 | }); 10 | return target; 11 | } 12 | -------------------------------------------------------------------------------- /packages/utils/libs/types.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Devorein/Nishan/5c258d07d6a5a9ea45a3b44ec04eb19018f4deda/packages/utils/libs/types.ts -------------------------------------------------------------------------------- /packages/utils/libs/updateLastEditedProps.ts: -------------------------------------------------------------------------------- 1 | import { NotionUtils } from './'; 2 | 3 | export function updateLastEditedProps (block: any, user_id: string) { 4 | const last_edited_props = { 5 | last_edited_time: Date.now(), 6 | last_edited_by_table: 'notion_user', 7 | last_edited_by_id: user_id 8 | }; 9 | NotionUtils.deepMerge(block, last_edited_props); 10 | return last_edited_props; 11 | } 12 | -------------------------------------------------------------------------------- /packages/utils/tests/createDefaultRecordMap.test.ts: -------------------------------------------------------------------------------- 1 | import { NotionConstants } from '@nishans/constants'; 2 | import { NotionUtils } from '../libs'; 3 | 4 | it(`createDefaultRecordMap`, () => { 5 | const created_default_record_map = NotionUtils.createDefaultRecordMap(); 6 | const data_types = NotionConstants.dataTypes(); 7 | data_types.forEach((data_type) => expect(Array.isArray(created_default_record_map[data_type])).toBe(true)); 8 | }); 9 | -------------------------------------------------------------------------------- /packages/utils/tests/deepMerge.test.ts: -------------------------------------------------------------------------------- 1 | import { NotionUtils } from '../libs'; 2 | 3 | afterEach(() => { 4 | jest.restoreAllMocks(); 5 | }); 6 | 7 | it(`Should work for object source and target`, () => { 8 | expect(NotionUtils.deepMerge({ a: { b: 2, c: 3 } }, { a: { b: 1 } })).toStrictEqual({ 9 | a: { 10 | b: 1, 11 | c: 3 12 | } 13 | }); 14 | }); 15 | 16 | it(`Should work for non object source`, () => { 17 | expect(NotionUtils.deepMerge({ a: { b: 2, c: 3 } }, false)).toStrictEqual({ a: { b: 2, c: 3 } }); 18 | }); 19 | 20 | it(`Should work for source key not in target`, () => { 21 | expect(NotionUtils.deepMerge({ a: { b: 2, c: 3 } }, { b: { c: 1 } })).toStrictEqual({ 22 | a: { b: 2, c: 3 }, 23 | b: { c: 1 } 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /packages/utils/tests/extractInlineBlockContent.test.ts: -------------------------------------------------------------------------------- 1 | import { NotionUtils } from '../libs'; 2 | 3 | it(`Works correctly`, () => { 4 | expect( 5 | NotionUtils.extractInlineBlockContent([ 6 | [ 'bold', [ [ 'b' ] ] ], 7 | [ 'italic', [ [ 'i' ], [ 'b' ] ] ], 8 | [ 'strikethrough', [ [ 's' ] ] ], 9 | [ 'code', [ [ 'c' ] ] ] 10 | ]) 11 | ).toBe('bolditalicstrikethroughcode'); 12 | }); 13 | -------------------------------------------------------------------------------- /packages/utils/tests/getSchemaMapUnit.test.ts: -------------------------------------------------------------------------------- 1 | import { tsu } from '../../fabricator/tests/utils'; 2 | import { NotionUtils } from '../libs'; 3 | 4 | it(`Should get schema map unit`, () => { 5 | const schema_map_unit = NotionUtils.getSchemaMapUnit(NotionUtils.generateSchemaMap({ title: tsu }), 'Title', []); 6 | expect(schema_map_unit).toStrictEqual({ ...tsu, schema_id: 'title' }); 7 | }); 8 | 9 | it(`Should throw if schema map unit doesn't exist`, () => { 10 | expect(() => NotionUtils.getSchemaMapUnit(NotionUtils.generateSchemaMap({ title: tsu }), 'title', [])).toThrow(); 11 | }); 12 | -------------------------------------------------------------------------------- /packages/utils/tests/getSchemaUnit.test.ts: -------------------------------------------------------------------------------- 1 | import { tsu } from '../../fabricator/tests/utils'; 2 | import { NotionUtils } from '../libs'; 3 | 4 | it(`returns schema unit`, () => { 5 | const schema_unit = NotionUtils.getSchemaUnit( 6 | { 7 | title: tsu 8 | }, 9 | 'title', 10 | [] 11 | ); 12 | expect(schema_unit).toStrictEqual(tsu); 13 | }); 14 | 15 | it(`Throw error for unknown property`, () => { 16 | expect(() => 17 | NotionUtils.getSchemaUnit( 18 | { 19 | title: tsu 20 | }, 21 | 'titles', 22 | [] 23 | ) 24 | ).toThrow(); 25 | }); 26 | -------------------------------------------------------------------------------- /packages/utils/tests/populateChildPath.test.ts: -------------------------------------------------------------------------------- 1 | import { NotionUtils } from '../libs'; 2 | 3 | describe('populateChildPath', () => { 4 | it(`Should work when path doesn't exist`, () => { 5 | const data: any = {}; 6 | NotionUtils.populateChildPath({ data, child_id: '123', child_path: 'child_ids' }); 7 | expect(data.child_ids).toStrictEqual([ '123' ]); 8 | }); 9 | 10 | it(`Should work when path does exist`, () => { 11 | const data: any = { child_ids: [ '456' ] }; 12 | NotionUtils.populateChildPath({ data, child_id: '123', child_path: 'child_ids' }); 13 | expect(data.child_ids).toStrictEqual([ '456', '123' ]); 14 | }); 15 | }); 16 | -------------------------------------------------------------------------------- /packages/utils/tests/updateLastEditedProps.test.ts: -------------------------------------------------------------------------------- 1 | import { NotionUtils } from '../libs'; 2 | 3 | it(`updateLastEditedProps`, () => { 4 | const data = {}; 5 | NotionUtils.updateLastEditedProps(data, 'user_1'); 6 | expect(data).toStrictEqual({ 7 | last_edited_time: expect.any(Number), 8 | last_edited_by_table: 'notion_user', 9 | last_edited_by_id: 'user_1' 10 | }); 11 | }); 12 | -------------------------------------------------------------------------------- /packages/utils/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.shared.json", 3 | "include": [ 4 | "./libs/index.ts", 5 | "./experiment", 6 | "./examples" 7 | ], 8 | "compilerOptions": { 9 | "outDir": "./dist", 10 | "rootDir": "./", 11 | }, 12 | } -------------------------------------------------------------------------------- /packages/validators/libs/checkDateSchemaUnit.ts: -------------------------------------------------------------------------------- 1 | import { NotionErrors } from '@nishans/errors'; 2 | import { TSchemaUnit } from '@nishans/types'; 3 | 4 | type ISchemaMapValue = { 5 | schema_id: string; 6 | } & TSchemaUnit; 7 | 8 | export function checkDateSchemaUnit (schema_map_unit: ISchemaMapValue, value: string, path: string[]) { 9 | if ( 10 | !schema_map_unit.type.match(/^(last_edited_time|created_time|date|formula)$/) || 11 | (schema_map_unit.type === 'formula' && schema_map_unit.formula.result_type !== 'date') 12 | ) 13 | throw new NotionErrors.unsupported_property_type(value, path, schema_map_unit.type, [ 14 | 'last_edited_time', 15 | 'created_time', 16 | 'date', 17 | 'formula' 18 | ]); 19 | } 20 | -------------------------------------------------------------------------------- /packages/validators/libs/checkSelectSchemaUnit.ts: -------------------------------------------------------------------------------- 1 | import { NotionErrors } from '@nishans/errors'; 2 | import { TSchemaUnit } from '@nishans/types'; 3 | 4 | export const checkSelectSchemaUnit = (schema_map_unit: { schema_id: string } & TSchemaUnit, path: string[]) => { 5 | if (schema_map_unit.type !== 'select' && schema_map_unit.type !== 'multi_select') 6 | throw new NotionErrors.unsupported_property_type(schema_map_unit.name, path, schema_map_unit.type, [ 7 | 'select', 8 | 'multi_select' 9 | ]); 10 | }; 11 | -------------------------------------------------------------------------------- /packages/validators/libs/dataContainsAliveProp.ts: -------------------------------------------------------------------------------- 1 | import { TDataType } from '@nishans/types'; 2 | export const dataContainsAliveProp = (data_type: TDataType) => 3 | Boolean(data_type.match(/^(block|space_view|collection_view|comment)$/)); 4 | -------------------------------------------------------------------------------- /packages/validators/libs/dataContainsEditedProps.ts: -------------------------------------------------------------------------------- 1 | import { TDataType } from '@nishans/types'; 2 | export const dataContainsEditedProps = (data_type: TDataType) => Boolean(data_type.match(/^(block|space|comment)$/)); 3 | -------------------------------------------------------------------------------- /packages/validators/libs/index.ts: -------------------------------------------------------------------------------- 1 | import { checkDateSchemaUnit } from './checkDateSchemaUnit'; 2 | import { checkSelectSchemaUnit } from './checkSelectSchemaUnit'; 3 | import { dataContainsAliveProp } from './dataContainsAliveProp'; 4 | import { dataContainsEditedProps } from './dataContainsEditedProps'; 5 | 6 | export const NotionValidators = { 7 | checkDateSchemaUnit, 8 | checkSelectSchemaUnit, 9 | dataContainsAliveProp, 10 | dataContainsEditedProps 11 | }; 12 | -------------------------------------------------------------------------------- /packages/validators/tests/checkSelectSchemaUnit.test.ts: -------------------------------------------------------------------------------- 1 | import { NotionValidators } from '../libs'; 2 | 3 | it(`Should throw error if schema_map_unit.type !== select`, () => { 4 | expect(() => 5 | NotionValidators.checkSelectSchemaUnit( 6 | { 7 | schema_id: 'text', 8 | type: 'text', 9 | name: 'Text' 10 | }, 11 | [] 12 | ) 13 | ).toThrow(); 14 | }); 15 | 16 | it(`Should work correctly if schema_map_unit.type === select`, () => { 17 | expect(() => 18 | NotionValidators.checkSelectSchemaUnit( 19 | { 20 | schema_id: 'select', 21 | type: 'select', 22 | name: 'Select', 23 | options: [] 24 | }, 25 | [] 26 | ) 27 | ).not.toThrow(); 28 | }); 29 | -------------------------------------------------------------------------------- /packages/validators/tests/dataContainsAliveProp.test.ts: -------------------------------------------------------------------------------- 1 | import { TDataType } from '@nishans/types'; 2 | import { NotionValidators } from '../libs'; 3 | 4 | describe(`dataContainsAliveProp`, () => { 5 | ([ 'block', 'space_view', 'collection_view', 'comment' ] as TDataType[]).forEach((data_type) => { 6 | it(`Should work for ${data_type}`, () => { 7 | expect(NotionValidators.dataContainsAliveProp(data_type)).toBe(true); 8 | }); 9 | }); 10 | 11 | it(`Should return false for space`, () => { 12 | expect(NotionValidators.dataContainsAliveProp('space')).toBe(false); 13 | }); 14 | }); 15 | -------------------------------------------------------------------------------- /packages/validators/tests/dataContainsEditedProps.test.ts: -------------------------------------------------------------------------------- 1 | import { TDataType } from '@nishans/types'; 2 | import { NotionValidators } from '../libs'; 3 | 4 | describe(`dataContainsEditedProps`, () => { 5 | ([ 'block', 'space', 'comment' ] as TDataType[]).forEach((data_type) => { 6 | it(`Should work for ${data_type}`, () => { 7 | expect(NotionValidators.dataContainsEditedProps(data_type)).toBe(true); 8 | }); 9 | }); 10 | 11 | it(`Should return false for space_view`, () => { 12 | expect(NotionValidators.dataContainsEditedProps('space_view')).toBe(false); 13 | }); 14 | }); 15 | -------------------------------------------------------------------------------- /packages/validators/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.shared.json", 3 | "include": [ 4 | "./libs/index.ts", 5 | "./experiment", 6 | "./examples" 7 | ], 8 | "compilerOptions": { 9 | "outDir": "./dist", 10 | "rootDir": "./", 11 | }, 12 | } -------------------------------------------------------------------------------- /scripts/libs/Extract/extractDependencies.ts: -------------------------------------------------------------------------------- 1 | export const extractDependencies = (dependencies: Record) => { 2 | const trimmed_dependencies: Record = {}; 3 | Object.keys(dependencies).forEach((dependency) => { 4 | if (dependency.startsWith('@nishans')) trimmed_dependencies[dependency] = dependencies[dependency]; 5 | }); 6 | 7 | return trimmed_dependencies; 8 | }; 9 | -------------------------------------------------------------------------------- /scripts/libs/Extract/extractModuleDependencies.ts: -------------------------------------------------------------------------------- 1 | import ts from 'typescript'; 2 | 3 | export const extractModuleDependencies = (module_path: string) => { 4 | const program = ts.createProgram([ module_path ], { allowJs: true }), 5 | sourceFile = program.getSourceFile(module_path)!, 6 | imported_module_dependencies: Set = new Set(); 7 | (sourceFile as any).imports.forEach((node: any) => { 8 | imported_module_dependencies.add(node.text); 9 | }); 10 | 11 | return imported_module_dependencies; 12 | }; 13 | -------------------------------------------------------------------------------- /scripts/libs/Extract/index.ts: -------------------------------------------------------------------------------- 1 | import { extractDependencies } from './extractDependencies'; 2 | import { extractModuleDependencies } from './extractModuleDependencies'; 3 | import { extractPackageDependencies } from './extractPackageDependencies'; 4 | import { extractPackageInstalledDependencies } from './extractPackageInstalledDependencies'; 5 | 6 | export const NishanScriptsExtract = { 7 | dependencies: extractDependencies, 8 | packageDependencies: extractPackageDependencies, 9 | moduleDependencies: extractModuleDependencies, 10 | packageInstalledDependencies: extractPackageInstalledDependencies 11 | }; 12 | -------------------------------------------------------------------------------- /scripts/libs/Get/getPackageJsonData.ts: -------------------------------------------------------------------------------- 1 | import fs from 'fs'; 2 | import path from 'path'; 3 | 4 | export const getPackageJsonData = async (package_name: string) => { 5 | const packages_dir = path.resolve(__dirname, '../../../../packages'); 6 | const package_dir = path.join(packages_dir, package_name.split('/')[1]), 7 | package_package_json_path = path.join(package_dir, 'package.json'); 8 | 9 | return { 10 | package_json_data: JSON.parse(await fs.promises.readFile(package_package_json_path, 'utf-8')), 11 | package_json_path: package_package_json_path 12 | }; 13 | }; 14 | -------------------------------------------------------------------------------- /scripts/libs/Get/getPackageJsonDependencies.ts: -------------------------------------------------------------------------------- 1 | import fs from 'fs'; 2 | import path from 'path'; 3 | 4 | export const getPackageJsonDependencies = async (package_name: string) => { 5 | const package_json_path = path.resolve(__dirname, `../../../../packages/${package_name}/package.json`); 6 | const package_json_data = JSON.parse(await fs.promises.readFile(package_json_path, 'utf-8')); 7 | return { ...(package_json_data.dependencies ?? {}), ...(package_json_data.devDependencies ?? {})} as Record; 8 | }; 9 | -------------------------------------------------------------------------------- /scripts/libs/Get/index.ts: -------------------------------------------------------------------------------- 1 | import { getOutdatedDeps } from './getOutdatedDeps'; 2 | import { getPackageJsonData } from './getPackageJsonData'; 3 | import { getPackageJsonDependencies } from './getPackageJsonDependencies'; 4 | import { getPackageNonInstalledDependencies } from './getPackageNonInstalledDependencies'; 5 | import { getPackagesNonInstalledDependencies } from './getPackagesNonInstalledDependencies'; 6 | 7 | export const NishanScriptsGet = { 8 | packageJsonDependencies: getPackageJsonDependencies, 9 | packageNonInstalledDependencies: getPackageNonInstalledDependencies, 10 | packagesNonInstalledDependencies: getPackagesNonInstalledDependencies, 11 | outdatedDeps: getOutdatedDeps, 12 | packageJsonData: getPackageJsonData 13 | }; 14 | -------------------------------------------------------------------------------- /scripts/libs/Install/index.ts: -------------------------------------------------------------------------------- 1 | import { installLinkedDeps } from './installLinkedDeps'; 2 | 3 | export const NishanScriptsInstall = { 4 | linkedDeps: installLinkedDeps 5 | }; 6 | -------------------------------------------------------------------------------- /scripts/libs/Install/installLinkedDeps.ts: -------------------------------------------------------------------------------- 1 | import cp from 'child_process'; 2 | import fs from 'fs'; 3 | import path from 'path'; 4 | 5 | export async function installLinkedDeps() { 6 | const root_dir = path.resolve(__dirname, '../../../../packages'); 7 | const packageNames = fs.readdirSync(root_dir); 8 | packageNames.forEach((packageName) => { 9 | const packageDirectory = path.join(root_dir, packageName); 10 | cp.execSync('npm install -g .', { cwd: packageDirectory }); 11 | console.log(`Globally installed @nishans/${packageName}`); 12 | }); 13 | } 14 | -------------------------------------------------------------------------------- /scripts/libs/Link/index.ts: -------------------------------------------------------------------------------- 1 | import { linkPackages } from './linkPackages'; 2 | 3 | export const NishanScriptsLink = { 4 | packages: linkPackages 5 | }; 6 | -------------------------------------------------------------------------------- /scripts/libs/Publish/index.ts: -------------------------------------------------------------------------------- 1 | import { publishAfterBuild } from './publishAfterBuild'; 2 | import { publishUpdatedPackages } from './publishUpdatedPackages'; 3 | 4 | export const NishanScriptsPublish = { 5 | afterBuild: publishAfterBuild, 6 | updatedPackages: publishUpdatedPackages 7 | }; 8 | -------------------------------------------------------------------------------- /scripts/libs/Update/index.ts: -------------------------------------------------------------------------------- 1 | import { updateOutdatedDeps } from './updateOutdatedDeps'; 2 | import { updatePackageDependency } from './updatePackageDependency'; 3 | import { updatePackageDescription } from './updatePackageDescription'; 4 | import { updatePackageMetadata } from './updatePackageMetadata'; 5 | import { updatePatchVersion } from './updatePatchVersion'; 6 | 7 | export const NishanScriptsUpdate = { 8 | packageDescription: updatePackageDescription, 9 | packageDependency: updatePackageDependency, 10 | packageMetadata: updatePackageMetadata, 11 | patchVersion: updatePatchVersion, 12 | outdatedDeps: updateOutdatedDeps 13 | }; 14 | -------------------------------------------------------------------------------- /scripts/libs/Update/updateOutdatedDeps.ts: -------------------------------------------------------------------------------- 1 | export const updateOutdatedDeps = async () => { 2 | /* const outdated_dependency_map = await NishanScripts.Get.outdatedDeps(); 3 | for (const { name } of packages_data) { 4 | await NishanScripts.Update.packageDependency(outdated_dependency_map, name); 5 | } */ 6 | }; 7 | -------------------------------------------------------------------------------- /scripts/libs/Update/updatePackageDescription.ts: -------------------------------------------------------------------------------- 1 | import fs from 'fs'; 2 | 3 | export async function updatePackageDescription (package_json_path: string, description: string) { 4 | const package_json_data = JSON.parse(await fs.promises.readFile(package_json_path, 'utf-8')); 5 | if (package_json_data.description !== description) { 6 | package_json_data.description = description; 7 | await fs.promises.writeFile(package_json_path, JSON.stringify(package_json_data, null, 2), 'utf-8'); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /scripts/libs/Update/updatePatchVersion.ts: -------------------------------------------------------------------------------- 1 | import { IPackageMap } from '../types'; 2 | 3 | export function updatePatchVersion (updated_package: string, package_map: IPackageMap, amount: number) { 4 | const package_info = package_map.get(updated_package)!; 5 | const [ major, minor, patch ] = package_info.version.split('.'); 6 | package_info.version = `${major}.${minor}.${parseInt(patch) + amount}`; 7 | package_map.set(updated_package, package_info); 8 | } 9 | -------------------------------------------------------------------------------- /scripts/libs/index.ts: -------------------------------------------------------------------------------- 1 | import { NishanScriptsCreate } from './Create'; 2 | import { NishanScriptsExtract } from './Extract'; 3 | import { NishanScriptsGet } from './Get'; 4 | import { NishanScriptsInstall } from './Install'; 5 | import { NishanScriptsLink } from './Link'; 6 | import { NishanScriptsPublish } from './Publish'; 7 | import { NishanScriptsUpdate } from './Update'; 8 | 9 | export const NishanScripts = { 10 | Get: NishanScriptsGet, 11 | Update: NishanScriptsUpdate, 12 | Publish: NishanScriptsPublish, 13 | Create: NishanScriptsCreate, 14 | Extract: NishanScriptsExtract, 15 | Install: NishanScriptsInstall, 16 | Link: NishanScriptsLink 17 | }; 18 | -------------------------------------------------------------------------------- /scripts/libs/types.ts: -------------------------------------------------------------------------------- 1 | export type IPackageInfo = { 2 | version: string; 3 | dependents: Record; 4 | dependencies: Record; 5 | name: string; 6 | description: string; 7 | published: boolean; 8 | }; 9 | 10 | export type IPackageMap = Map; 11 | export interface IPackageDependencyMap { 12 | main: Map; 13 | direct: Map; 14 | indirect: Map; 15 | all: Map; 16 | } 17 | 18 | export type IPackageDependencyVersionMap = Map>; 19 | -------------------------------------------------------------------------------- /scripts/libs/utils/index.ts: -------------------------------------------------------------------------------- 1 | export * from './jsonReplacer'; 2 | export * from './jsonReviver'; 3 | -------------------------------------------------------------------------------- /scripts/libs/utils/jsonReplacer.ts: -------------------------------------------------------------------------------- 1 | export const jsonReplacer = (_: string, value: any) => { 2 | if (value instanceof Map) { 3 | return { 4 | dataType: 'Map', 5 | value: Array.from(value.entries()) // or with spread: value: [...value] 6 | }; 7 | } else { 8 | return value; 9 | } 10 | }; 11 | -------------------------------------------------------------------------------- /scripts/libs/utils/jsonReviver.ts: -------------------------------------------------------------------------------- 1 | export function jsonReviver (key: string, value: any) { 2 | if (typeof value === 'object' && value !== null) { 3 | if (value.dataType === 'Map') { 4 | return new Map(value.value); 5 | } 6 | } 7 | return value; 8 | } 9 | -------------------------------------------------------------------------------- /scripts/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@nishans/scripts", 3 | "version": "1.0.0", 4 | "description": "A collection of libs for automating manual package related tasks", 5 | "main": "dist/libs/index.js", 6 | "typings": "dist/libs/index.d.ts", 7 | "scripts": { 8 | "build": "npx tsc", 9 | "build:watch": "npx tsc -w" 10 | }, 11 | "keywords": [], 12 | "author": "Safwan Shaheer ", 13 | "license": "MIT", 14 | "dependencies": { 15 | "tsc-prog": "^2.2.1", 16 | "typescript": "^4.2.3" 17 | }, 18 | "optionalDependencies": { 19 | "colors": "1.4.0", 20 | "glob": "^7.1.6", 21 | "rehype": "^11.0.0", 22 | "remark": "^13.0.0", 23 | "ts-dedent": "2.0.0" 24 | } 25 | } -------------------------------------------------------------------------------- /scripts/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.shared.json", 3 | "include": [ 4 | "./libs/**/*.ts", 5 | "./experiment" 6 | ], 7 | "compilerOptions": { 8 | "target": "es2015", 9 | "outDir": "./dist", 10 | "rootDir": "./", 11 | "resolveJsonModule": true 12 | } 13 | } -------------------------------------------------------------------------------- /scripts/uploadTestCoverageReports.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | codecov_file="${GITHUB_WORKSPACE}/scripts/codecov.sh" 4 | 5 | curl -s https://codecov.io/bash > $codecov_file 6 | chmod +x $codecov_file 7 | 8 | cd "${GITHUB_WORKSPACE}/packages"; 9 | 10 | for dir in */ 11 | do 12 | package="${dir/\//}" 13 | if [ -d "$package/coverage" ] 14 | then 15 | file="$PWD/$package/coverage/lcov.info" 16 | flag="${package/-/_}" 17 | $codecov_file -f $file -F $flag -v -t $CODECOV_TOKEN 18 | fi 19 | done -------------------------------------------------------------------------------- /tsconfig.shared.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "lib": [ 4 | "ESNext", 5 | "dom", 6 | ], 7 | "baseUrl": "./", 8 | "module": "commonjs", 9 | "moduleResolution": "node", 10 | "target": "ES2015", 11 | "strict": true, 12 | "esModuleInterop": true, 13 | "skipLibCheck": true, 14 | "forceConsistentCasingInFileNames": true, 15 | "watch": false, 16 | "declaration": true, 17 | "sourceMap": true, 18 | "noUnusedLocals": false, 19 | "incremental": false 20 | } 21 | } -------------------------------------------------------------------------------- /utils/tests/createDefaultNishanArg.ts: -------------------------------------------------------------------------------- 1 | import { NotionCache } from '@nishans/cache'; 2 | import { INotionCoreOptions } from '@nishans/core'; 3 | 4 | export const creatDefaultNishanArg = () => { 5 | return { 6 | cache: NotionCache.createDefaultCache(), 7 | id: 'block_1', 8 | interval: 0, 9 | space_id: 'space_1', 10 | token: 'token', 11 | user_id: 'user_root_1', 12 | logger: true, 13 | notion_operation_plugins: [], 14 | cache_init_tracker: NotionCache.createDefaultCacheInitializeTracker() 15 | } as INotionCoreOptions; 16 | }; 17 | -------------------------------------------------------------------------------- /utils/tests/executeOperationsMock.ts: -------------------------------------------------------------------------------- 1 | import { NotionOperations } from '@nishans/operations'; 2 | import { IOperation } from '@nishans/types'; 3 | 4 | export const createExecuteOperationsMock = () => { 5 | const executeOperationsMock = jest 6 | .spyOn(NotionOperations, 'executeOperations') 7 | .mockImplementation(async () => undefined); 8 | 9 | return { 10 | executeOperationsMock, 11 | e1 (ops: IOperation[]) { 12 | expect(executeOperationsMock.mock.calls[0][0]).toStrictEqual(ops); 13 | }, 14 | e2 (ops: IOperation[]) { 15 | expect(executeOperationsMock.mock.calls[1][0]).toStrictEqual(ops); 16 | } 17 | }; 18 | }; 19 | -------------------------------------------------------------------------------- /utils/tests/index.ts: -------------------------------------------------------------------------------- 1 | export * from './createDefaultNishanArg'; 2 | export * from './executeOperationsMock'; 3 | --------------------------------------------------------------------------------