mikser-io 6.15.0 → 6.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mikser-io",
3
- "version": "6.15.0",
3
+ "version": "6.17.0",
4
4
  "description": "<p align=\"center\"> <img src=\"mikser-lockup-stacked.svg\" alt=\"mikser\" width=\"198\" /> </p>",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -36,9 +36,18 @@ export default ({
36
36
  }
37
37
  }
38
38
  for (let entitiesName in entitiesConfig) {
39
+ // Per-config namespacing token. When set, this entity-writer's
40
+ // files land under <dataFolder>/<token>/ instead of straight
41
+ // in <dataFolder>. Each named entity config can declare its
42
+ // own token, so they can target different namespaces (useful
43
+ // for multi-tenant exports into shared storage).
44
+ const token = entitiesConfig[entitiesName].token
45
+ const targetFolder = token
46
+ ? path.join(runtime.options.dataFolder, token)
47
+ : runtime.options.dataFolder
39
48
  const {
40
49
  query,
41
- map,
50
+ map: mapEntity = entity => entity,
42
51
  pick,
43
52
  save: saveEntity = async entity => {
44
53
  if (!entity.name) {
@@ -46,12 +55,12 @@ export default ({
46
55
  return
47
56
  }
48
57
  const dump = JSON.stringify(normalize(entity))
49
- const entityFile = path.join(runtime.options.dataFolder, `${entity.name}.${entitiesName}.json`)
58
+ const entityFile = path.join(targetFolder, `${entity.name}.${entitiesName}.json`)
50
59
  await mkdir(path.dirname(entityFile), { recursive: true })
51
60
  await writeFile(entityFile, dump, 'utf8')
52
61
  },
53
62
  delete: deleteEntity = async entity => {
54
- const entityFile = path.join(runtime.options.dataFolder, `${entity.name}.json`)
63
+ const entityFile = path.join(targetFolder, `${entity.name}.json`)
55
64
  await unlink(entityFile)
56
65
  }
57
66
  } = entitiesConfig[entitiesName]
@@ -62,12 +71,12 @@ export default ({
62
71
  case OPERATION.CREATE:
63
72
  case OPERATION.UPDATE:
64
73
  logger.debug('Data export entity %s %s: %s', entity.collection, operation, entity.id)
65
- await saveEntity(map ? await map(entity) : {
74
+ await saveEntity(({
66
75
  refId: ('/' + entity.name.replaceAll('\\', '/')).replace(/\/index$/g, '/'),
67
76
  name: entity.name,
68
77
  date: new Date(entity.time),
69
- data: _.pick(entity, pick || ['collection', 'format', 'type', 'destination', 'stamp', 'meta', 'id',])
70
- })
78
+ data: _.pick(await mapEntity(entity), pick || ['collection', 'format', 'type', 'destination', 'stamp', 'meta', 'id',])
79
+ }))
71
80
  break
72
81
  case OPERATION.DELETE:
73
82
  await deleteEntity(entity)
@@ -90,14 +99,19 @@ export default ({
90
99
  }
91
100
  }
92
101
  for (let contextName in contextConfig) {
102
+ // Per-config namespacing token — see the entities loop above.
103
+ const token = contextConfig[contextName].token
104
+ const targetFolder = token
105
+ ? path.join(runtime.options.dataFolder, token)
106
+ : runtime.options.dataFolder
93
107
  const {
94
108
  query,
95
- map,
109
+ map: mapEntityContext = (entity, context) => context,
96
110
  pick,
97
111
  save: saveConext = async (entity, context) => {
98
112
  if (context?.data) {
99
113
  const entityName = entity.name
100
- const contextFile = path.join(runtime.options.dataFolder, `${entityName}.${contextName}.json`)
114
+ const contextFile = path.join(targetFolder, `${entityName}.${contextName}.json`)
101
115
  await mkdir(path.dirname(contextFile), { recursive: true })
102
116
  await writeFile(contextFile, JSON.stringify(context), 'utf8')
103
117
  }
@@ -107,7 +121,7 @@ export default ({
107
121
  for await (let { entity, context } of useJournal('Data context', [OPERATION.RENDER])) {
108
122
  if (query(entity)) {
109
123
  logger.debug('Data export context: %s', entity.name)
110
- await saveConext(entity, map ? await map(entity, context) : _.pick(context, pick || ['data']))
124
+ await saveConext(entity, _.pick(await mapEntityContext(entity, context), pick || ['data']))
111
125
  }
112
126
  }
113
127
  }
@@ -116,23 +130,29 @@ export default ({
116
130
  onFinalize(async () => {
117
131
  const logger = useLogger()
118
132
  for (let catalogName in runtime.config.data?.catalog || {}) {
133
+ // Per-config namespacing token — see the entities loop above.
134
+ const token = runtime.config.data?.catalog[catalogName].token
135
+ const targetFolder = token
136
+ ? path.join(runtime.options.dataFolder, token)
137
+ : runtime.options.dataFolder
119
138
  const {
120
139
  query: queryEntities = entity => entity.type == 'document',
121
- map,
140
+ map: mapEntity = entity => entity,
122
141
  pick,
123
142
  save: saveEntities = async entities => {
124
- const entitiesFile = path.join(runtime.options.dataFolder, `${catalogName}.json`)
143
+ const entitiesFile = path.join(targetFolder, `${catalogName}.json`)
144
+ await mkdir(path.dirname(entitiesFile), { recursive: true })
125
145
  logger.debug('Data export catalog %s %s: %s', catalogName, entities.length, entitiesFile)
126
146
  await writeFile(entitiesFile, JSON.stringify(entities), 'utf8')
127
147
  }
128
148
  } = runtime.config.data?.catalog[catalogName]
129
149
  const entities = await findEntities(queryEntities)
130
- await saveEntities(await pMap(entities, async entity => map ? await map(entity) : {
150
+ await saveEntities(await pMap(entities, async entity => ({
131
151
  refId: ('/' + entity.name.replaceAll('\\', '/')).replace(/\/index$/g, '/'),
132
152
  name: entity.name,
133
153
  date: new Date(entity.time),
134
- data: _.pick(entity, pick || ['collection', 'format', 'type', 'destination', 'stamp', 'meta', 'id',])
135
- }))
154
+ data: _.pick(await mapEntity(entity), pick || ['collection', 'format', 'type', 'destination', 'stamp', 'meta', 'id',])
155
+ })))
136
156
  }
137
157
  })
138
158
  }
@@ -24,6 +24,7 @@ export default ({
24
24
  trackProgress,
25
25
  updateProgress,
26
26
  updateEntry,
27
+ matchEntity,
27
28
  constants: { OPERATION },
28
29
  }) => {
29
30
  const collection = 'resources'
@@ -65,8 +66,7 @@ export default ({
65
66
  _.eachDeep(entity.meta, resource => {
66
67
  if (typeof resource == 'string') {
67
68
  for (let library in resourceLib) {
68
- const match = new RegExp(library)
69
- if (resource.match(match)) {
69
+ if (matchEntity(resource, library)) {
70
70
  resourceMap[entity.id].push({ library, resource, entity })
71
71
  }
72
72
  }
package/src/utils.js CHANGED
@@ -49,9 +49,9 @@ export function matchEntity(entity, match) {
49
49
  if (typeof match == 'function') return match(entity)
50
50
  else if (typeof match == 'string') {
51
51
  if (match.substring(0, 2) == '@/') {
52
- return minimatch(entity.name, match.substring(2))
52
+ return minimatch(typeof entity == 'string' ? entity : entity.name, match.substring(2))
53
53
  } else {
54
- return minimatch(entity.id, match)
54
+ return minimatch(typeof entity == 'string' ? entity : entity.id, match)
55
55
  }
56
56
  }
57
57
  else if (typeof match == 'object') return _.isMatch(entity, match)